• (三十八)从私人通讯录引出的细节II -数据逆传 -tableView点击 -自定义分割线


    项目中的警告是不会影响app发布的,例如引入第三方类库很容易引入警告。

    细节1:跳转的数据传递。

    prepareForSegue: sender: 方法是在执行segue后,跳转之前调用这个方法,一般在这里给下一个控制器传递数据。

    可以直接在这里获取目标控制器:如果只是简单的修改,不必一定写成真实的控制器类型

    UIViewController *contactVc = segue.destinationViewController;

    这样就可以修改目标视图的内容了。

    Tip:控制器的title属性等价于Navigation的title属性。

    Tip:segue的perform方法被执行时会跳转。

    Tip:performSegueWithIdentifier: sender: 方法的sender参数会传递到perpareForSegue函数内。


    细节2:输入信息的页码,键盘自动弹出。

    应该在viewDidAppear方法中,让第一个输入框成为第一响应者:叫出键盘。

    Tip:不要忘记调用super的这个方法!

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        
        // 让姓名文本框成为第一响应者(叫出键盘)
        [self.nameField becomeFirstResponder];
    }



    细节3:反向传递数据(从目标控制器传递到源控制器)。

    联系人添加完毕后要将数据添加回联系人列表,返回是pop操作,不存在Segue。

    联系人添加视图要在完成时调用联系人列表的代理方法,因此应该为联系人添加视图设置代理(delegate用weak),让联系人列表成为代理。

    Tip:delegate用weak。

    注意在添加之前将目标控制器(联系人添加视图)的delegate为联系人列表,以保证联系人列表可以监听到联系人添加的代理方法。

    只需要在联系人列表中实现这个方法即可。

    Tip:联系人列表是可变的,应该使用NSMutableArray,注意框架中的类型用strong。

    @property (nonatomic, strong) NSMutableArray *contacts;

    对于数组的初始化,应该是重写get方法进行懒加载。

    - (NSMutableArray *)contacts
    {
        if (_contacts == nil) {
            _contacts = [NSMutableArray array];
        }
        return _contacts;
    }

    Tip:代理的标准写法是第一个参数为调用代理方法的对象。

    Tip:代理的一个作用是解耦(解除耦合性)。

    关于@property的复习:

    copy用于NSString和NSMutaleString、block

    weak用于代理(delegate对象)和UI控件

    strong用于其他OC对象

    assign用于基本数据类型,注意枚举和结构体也属于基本数据类型


    关于模型的补充:

    如果不是用字典来初始化数据,可以不用KVC,因为创建字典也是个繁琐的过程。


    细节4:点击TableViewCell实现跳转到编辑:

    拖动cell到要跳转到的视图,选择Selection Segue的push(如果有NavigationController),是自动Segue。



    Tip:如果自定义cell已经有了标识,不需要再判断从缓存池中取出的是否为空,因为如果缓存池中没有会去storyboard中自动创建ID相符的

    注意一跳多(联系人列表跳到编辑或者添加),要判断segue的目标控制器类型

    使用NSObject的方法(通用方法)isKindOfClass:[XXX class],例如判断segue的目标控制器是不是MJAddViewController,如下:

    根据目标控制器的类型不同进行分别处理。

    Tip:isKindOfClass方法可以透过id类型“看穿”真正的类型。

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        id vc = segue.destinationViewController;
        
        if ([vc isKindOfClass:[MJAddViewController class]]) { // 如果是跳转到添加联系人的控制器
            // 设置下一个控制器(添加联系人的控制器)的代理
            MJAddViewController *addVc = vc;
            addVc.delegate = self;
        } else if ([vc isKindOfClass:[MJEditViewController class]]) { // 如果是跳转到查看(编辑)联系人的控制器
            MJEditViewController *editVc = vc;
            // 取得选中的那行
            NSIndexPath *path = [self.tableView indexPathForSelectedRow];
            editVc.contact = self.contacts[path.row];
            editVc.delegate = self;
        }
    }
    

    细节5:编辑页面应该利用BarButtonItem来控制是否可以编辑,点击编辑开始编辑(自动弹出键盘),然后编辑按钮变为取消,点击取消则退出编辑。

    Tip:tableView的indexPathForSelectedRow可以获得选中的行。

    注意,在顺传数据到下一个控制器时,在perpareForSegue方法中还没有创建下一个控制器的控件,因此在目标控制器的set方法中接收到模型进行控件初始化是不会成功的,应该在viewDidLoad方法中进行模型数据到控件的初始化


    Tip:由于指向数组和模型的都是指针,因此不论是哪里的指针修改了原来的内容都会变化。


    细节6:tableView的分割线设定为没有内容的没有分割线,有内容的有分割线,系统并不支持,应该隐藏系统的线,然后自己加一条线。

    系统自带的分割线的实质就是View。

    首先应当取消系统自带的分割线:

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    为了自定义分割线,应该在cell的初始化方法中进行,但是从storyboard(xib)中创建的cell不会调用initWithStyle方法来初始化cell(手写代码创建cell时才会调用),但是会调用awakeFromNib方法,因此应该在这个方法里面初始化cell:

    Tip:注意不要在初始化方法中修改frame,因为这时的frame还不是最终尺寸,应该在layoutSubviews方法中初始化。

    //从storyboard或者xib中创建的,会调用这个方法。
    - (void)awakeFromNib{
        
        UIView *divider = [[UIView alloc] init];
        divider.backgroundColor = [UIColor blackColor];
        [self.contentView addSubview:divider];
        
    }

    在layoutSubviews来修改frame:

    //从这里拿到的尺寸是最终的
    - (void)layoutSubviews{
        
        CGFloat dividerW = self.frame.size.width;
        CGFloat dividerH = 1;
        CGFloat dividerX = 0;
        CGFloat dividerY = self.frame.size.height - dividerH;
        self.divider.alpha = 0.2;
        self.divider.frame = CGRectMake(dividerX, dividerY, dividerW, dividerH);
        
    }



  • 相关阅读:
    About HDFS blocks
    Hadoop源代码分析(一)
    Hadoop源代码分析(三)
    MapReduce基础
    Pig安装与配置教程
    MapReduce数据流(三)
    MapReduce数据流(二)
    c++中的临时对象
    如何修改CMD命令行窗口下的默认路径
    VC2005: warning LNK4076: 无效的增量状态文件
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154213.html
Copyright © 2020-2023  润新知