学习Mac开发第八弹 学习NSTableView Cell Base

本文介绍如何使用 Swift 在 TableView 中展示用户详情数据,并实现单元格的高度设置、内容居中及响应单双击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 创建列表

    1. 在故事版上的ViewContoller 上面拖拽个tablview 并且把列表代理拖拽到控制器上。
    2. 设置3个栏目如下图
      这里写图片描述

    3. 分别设置3个栏目名称为ID ,name image

    4. 指定每个栏目对象cell的唯一标识符
      对应如下
      ID->userid name->username image->useravatar
      把image下面的TextCell 修改为imageCell 用来显示图片

    这里写图片描述

    1. 创建个UserDetailDataModel 数据Model 属性名称要和上面的标识符对应
    
    
    #import <Foundation/Foundation.h>
    
    
    @interface UserDetailDataModel : NSObject
    @property (strong, nonatomic)NSString *userid;
    @property (strong, nonatomic)NSString *username;
    @property (strong, nonatomic)NSImage *useravatar;
    @end
    
    1. 设置tablview delegate 和datasource
    //  ViewController.m
    //  NSTablviewDemo
    //
    //  Created by 冷胜任 on 16/12/26.
    //  Copyright © 2016年 Alijk.com. All rights reserved.
    //
    
    
    #import "ViewController.h"
    
    
    #import "UserDetailDataModel.h"
    
    @interface ViewController () <NSTableViewDelegate, NSTableViewDataSource>
    @property (strong, nonatomic)NSMutableArray *dataSource;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.dataSource = [NSMutableArray new];
        //设置Cell 高度
        [self.tablview setRowHeight:45];
    
        //创建数据Model
        NSArray *userIdArray = @[@"101",@"102",@"103",@"104"];
        NSArray *userNameArray = @[@"Allen",@"Jack",@"Luck",@"Tony"];
        NSArray *userAvatarArray = @[[NSImage imageNamed:@"tag_1.png"],[NSImage imageNamed:@"tag_2.jpg"],[NSImage imageNamed:@"tag_3.jpg"],[NSImage imageNamed:@"tag_4.jpeg"]];
    
        for (NSInteger i = 0; i < userNameArray.count; i++) {
            UserDetailDataModel *detail = [[UserDetailDataModel alloc]init];
            detail.userid = userIdArray[i];
            detail.username = userNameArray[i];
            detail.useravatar = userAvatarArray[i];
            [self.dataSource addObject:detail];
    
        }
    
         [self.tablview reloadData];
        // Do any additional setup after loading the view.
    }
    
    
    #pragma mark TablviewDataSource
    
    
    //cell 个数
    - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
        return  self.dataSource.count;
    }
    
    //设置列表Value
    - (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
    {
        if([self.dataSource count] <= 0){
            return nil;
        }
        UserDetailDataModel *detail = self.dataSource[row];
    
        return   [detail valueForKey: [tableColumn identifier]];
    }
    //cell绑定对象模型
    - (void)tableView:(NSTableView *)tableView setObjectValue:(nullable id)object forTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row {
        UserDetailDataModel *detail = self.dataSource[row];
        [detail setValue:object forKey: [tableColumn identifier]];
    }
    
    
    - (void)setRepresentedObject:(id)representedObject {
        [super setRepresentedObject:representedObject];
    
        // Update the view, if already loaded.
    }
    

    效果如下
    这里写图片描述

  • 列表高度设置

      [self.tablview setRowHeight:45];

    或者

    - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row{
        return 45;
    }
    
  • 设置标题居中

    这里写图片描述

  • 设置列表文字居中

    设置Text Cell 居中模式
    这里写图片描述

    效果如下
    这里写图片描述

    总觉得怪怪的,居然没有上下居中这么能忍 Google 下,解决方案重写NSTextFieldCell

    
    #import <Cocoa/Cocoa.h>
    
    
    
    @interface RSVerticallyCenteredTextFieldCell : NSTextFieldCell
    {
        BOOL mIsEditingOrSelecting;
    }
    
    @end
    
    #import "RSVerticallyCenteredTextFieldCell.h"
    
    
    @implementation RSVerticallyCenteredTextFieldCell
    
    - (NSRect)drawingRectForBounds:(NSRect)theRect
    {
        // Get the parent's idea of where we should draw
        NSRect newRect = [super drawingRectForBounds:theRect];
    
        // When the text field is being 
        // edited or selected, we have to turn off the magic because it screws up 
        // the configuration of the field editor.  We sneak around this by 
        // intercepting selectWithFrame and editWithFrame and sneaking a 
        // reduced, centered rect in at the last minute.
        if (mIsEditingOrSelecting == NO)
        {
            // Get our ideal size for current text
            NSSize textSize = [self cellSizeForBounds:theRect];
    
            // Center that in the proposed rect
            float heightDelta = newRect.size.height - textSize.height;  
            if (heightDelta > 0)
            {
                newRect.size.height -= heightDelta;
                newRect.origin.y += (heightDelta / 2);
            }
        }
    
        return newRect;
    }
    - (void)selectWithFrame:(NSRect)rect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(nullable id)delegate start:(NSInteger)selStart length:(NSInteger)selLength
    {
        rect = [self drawingRectForBounds:rect];
        mIsEditingOrSelecting = YES;    
        [super selectWithFrame:rect inView:controlView editor:textObj delegate:delegate start:selStart length:selLength];
        mIsEditingOrSelecting = NO;
    }
    
    - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent
    {   
        aRect = [self drawingRectForBounds:aRect];
        mIsEditingOrSelecting = YES;
        [super editWithFrame:aRect inView:controlView editor:textObj delegate:anObject event:theEvent];
        mIsEditingOrSelecting = NO;
    }
    
    @end
    

    代码来自

    修改成重写的类
    这里写图片描述

    效果如图
    这里写图片描述

  • 监听单击事件

    - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
    {
        NSInteger currenSelectRow = [self.tablview selectedRow];
        NSLog(@"selectRow=========%ld",(long)currenSelectRow);
    
    }
  • 添加双击事件

    在viewDidLoad里面添加如下代码

    [self.tablview setDoubleAction:@selector(tableViewDoubleClicked)];
    self.tablview.allowsEmptySelection =  YES;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值