我们平时在设计页面的时候,考虑到MVC的设计模式会出现很多层的试图分离,这里面就不可以避免的出现自定的控件。
我在一次自定义控件中出现了以下问题,记录在案以供大家注意和参考。
(1)UIScrollView 对于加载在它上层试图中的手势无影响,但对上上层时图的手势就会失去响应。具体原因考虑到是 UIResponder 的事件传递中出现了事件劫持。
(2)当我们自定义控件时,如果控件中包括了UITextFeild 就要考虑到在用到这个自定义的控件的试图的键盘遮挡输入框的情况,一般自定义试图都继承于 BaseView,在这里有键盘遮挡统一的处理方法,但是要求子试图的 大小要跟屏幕一样大才行,一般自定义控件可能是很小的,所以这个自定义控件就不能继承 BaseView,它的上层View可以继承于 BaseView ,使用代理,当自定义控件中的UITextFeild 被编辑时通知上层试图,调用上层试图处理键盘遮罩的方法,动态的改变上层试图的位置即可。
(3)给自定义控件初始化的时候可以使用Frame,也可以使用Layout
使用Frame:x,y 坐标初始化为0,大小确定即可,使用Layout 来布局位置。如下,注意Layout布局里的大小要和 Frame里面的大小一样。自定义控件里面子视图的初始化写在 initWithFrame中
LMRecordVoiceView *recordView = [[LMRecordVoiceView alloc]initWithFrame:RECT(0, 0, 320, 60,1)]; [self.view addSubview:recordView]; recordView.sd_layout.leftSpaceToView(self.view,Scale_X(0)).topSpaceToView(self.view,Scale_Y(0)).rightSpaceToView(self.view,Scale_X(0)).heightIs(Scale_X(60));
使用SDAutoLayout:自定义控件的子视图初始化写在自定义的方法中如:initSubView,待自定义控件使用SDAutoLayout设置好后,再调用这个自定义控件中的自定义方法来初始化里面的子视图即可。
AutolayoutView *view1 = [AutolayoutView new]; view1.tag = 100; view1.backgroundColor = [UIColor blueColor]; [self.view addSubview:view1]; view1.sd_layout.leftSpaceToView(self.view,20).topSpaceToView(self.view,80).widthIs(200).heightIs(80); [view1 initSubView];
++++++++++++++++
AutolayoutView *view2 = [AutolayoutView new]; view2.tag = 200; view2.backgroundColor = [UIColor greenColor]; [self.view addSubview:view2]; view2.sd_layout.leftSpaceToView(self.view,20).topSpaceToView(self.view,200).widthIs(100).heightIs(140); [view2 initSubView];
(4)A加载到B上时,A调用B中的方法(A让B为期做事)需要代理或者回调,B调用A的方法(B让A为其做事),就直接用A的一个实例话对象调用A中的方法即可。
心得:
一个复杂系统的编写,不是一触而就的,也行在最初的全局设计的时候就需要发费很多的时间,但是这个时间是值得的,总比做到一半发现使用的方式是很low的,或者是走不通的要好。在没有思路的时候,可以先把最有把握的设计先完成,这样会渐渐的产生新的思路,一步一步走下去就回有好的设计方案产生,刚开始就想写出完美的设计或者完善的设计是不现实的,反而会增加思维压力,人为加大了开发的难度。
一个巧妙的设计如果不写注释就回让后续接手的人痛苦不堪,因为外人根本不知道自己所谓的“巧妙逻辑”,如:为了在众多情况中,使用一种公共的方法,就会把 for循环的中的 i 和数组中的 下标 i 联系在一起,借力打力,进而写出看似很简单的代码,实则是大大降低了代码的可读性。“巧妙”就带来了逻辑的复杂,鱼和熊掌难以兼得。