ShannonChenCHN / iOSDevLevelingUp

A journey of leveling up iOS development skills and knowledge.
365 stars 105 forks source link

How to make a custom control #45

Open ShannonChenCHN opened 7 years ago

ShannonChenCHN commented 7 years ago
ShannonChenCHN commented 7 years ago

延伸阅读:

ShannonChenCHN commented 7 years ago

How To Make a Custom Control Tutorial: A Reusable Slider 的学习总结

目录

学习笔记

  1. Choose a existing class for custom control to subclass or extend: You’ll be using the target-action pattern in this custom control, so UIControl will serve as a great starting point.

    1. Before you write any code for your control, you should add your control to the view controller so that you can watch the evolution of the control.

    2. API Design: Before you add the visual elements to your control, you’ll need a few properties to keep track of the various pieces of information that are stored in your control.

    3. Well-designed controls should define some default property values.

    4. Images vs. CoreGraphics 5.1 Images: Simple to use, but it’s difficult to modify the control from code. 5.2 Core Graphics: More flexible, but you have to write the rendering code yourself. 5.3 Apple tend to opt for using images in their controls.(You could see that UISlider uses images to configure appearance from API and by debugging view hierarchy.)

    5. Adding Interactive Logic: store which thumb is being dragged, and reflect that in the UI.

    6. Adding Touch Handlers: add the ability for the user to drag the slider thumbs around. 7.1 UIControl provides several methods for tracking touches, so we can override these methods to add interaction logic. 7.2 beginTrackingWithTouch(:with:) 7.3 continueTrackingWithTouch(:with:) 7.4 endTrackingWithTouch(:with:)

    7. Change Notifications

      • NSNotification, Key-Value-Observing (KVO): If you look at the UIKit controls, you’ll find they don’t use NSNotification or encourage the use of KVO, so for consistency with UIKit you can exclude those two options. - the delegate pattern:
      • A protocol can contain a number of methods.
      • A delegate method can take any number of parameters.
      • A control only accept a single delegate instance.
      • the target-action pattern:
      • The target-action pattern is provided by the UIControl base class.
      • You can provide multiple targets to control actions.
      • while it is possible to create custom events (see UIControlEventApplicationReserved) the number of custom events is limited to 4.
      • Control actions do not have the ability to send any information with the event.
      • The key differences between the above two patterns are as follows:
      • Multicast: one-to-one vs. one-to-many
      • Flexibility: can pass extra information vs. cannot pass extra information directly
    8. Modifying Your Control With Core Graphics: override draw(in:) method

    9. Handling Changes to Control Properties: implement property observers that update the control’s frame or drawing.

    10. Test: When you are developing a custom control, it’s your responsibility to exercise all of its properties and visually verify the results. A good way to approach this is to create a visual test harness with various buttons and sliders, each of which connected to a different property of the control. That way you can modify the properties of your custom control in real time — and see the results in real time.

    11. Where To Go From Here?

      • Documentation: A good practice is to provide public API documentation, at a minimum, for all publicly shared code. This means documenting all public classes and properties.
    • Robustness: You need to ensure that the control state always remains valid — despite what some silly coder tries to do to it.

    • API Design: Creating a flexible, intuitive and robust API will ensure that your control can be widely used, as well as wildly popular. See Matt Gemmell’s 25 rules of API design.

    • Sharing: GitHub, CocoaPods, Cocoa Controls

问题与收获

1.平时自己写的自定义 UI 控件一般都是继承 UIView,这个教程让我进一步见识了 UIControl 的价值,还是得多看看官方的 API Reference 和 Guides 。

2.一个功能、一个控件、一个框架的实现都不是一蹴而就的,这是一个不断进化、完善的过程。

3.要想受欢迎,一个框架/库的 API 一定要设计好,使用简单、功能齐全、文档清晰,推荐阅读 Matt Gemmell’s 25 rules of API design

4.实现一个控件的外观一般有两种方式:

5.写代码前需要想清楚要做哪几件事,比如写好一个自定义 control,就需要考虑:要继承什么类、API 怎么设计、外观展示怎么实现(subviews 和 sublayers、images 和 CoreGraphics)、交互逻辑怎么处理(touch 事件)、事件和数据怎么传递(target-action等)。

6.事件传递的几种方式:

7.自测:一个好的程序应该是经过广泛覆盖的测试的,写程序总会有 bug 的,谁也无法保证他自己写过的代码永远不会出 bug,所以写完代码后减低 bug 出现率的最佳方式是 realtime test。

8.鲁棒性:优秀的程序员一定不能不考虑代码的健壮性,各种边界情况以及框架使用者的错误使用方式都要考虑,比如需要用断言提前判断是否传入空值,预防使用者设置最大值比最小值还小的情况。

9.文档:代码除了写了给机器运行之外,还要给人去读的,对于那些开源软件来说,需要更加注意这点,好的文档就如同产品说明书一般,使用者用起来也方便,YYKit 的代码就是最佳典范。

10.分享:把有价值的代码分享出去,既能帮助别人快速开发,又能提供给别人参考学习,除此之外,还能得到不同人的意见和建议、反馈(issue、pull request)。还有一点就是被人 star 的满足感。

11.更多 Swift 相关的问题见练习代码中的 // TODO:标记。

ShannonChenCHN commented 7 years ago

Custom Controls 的学习总结

学习笔记

1. Overview of the View Hierarchy

3. Custom Interaction:communication strategies between views and their owners

4. Accessibility

5. Localization

6. Testing

问题与收获

1.UIResponder 与 UIResponder Chain #51 2.touch 事件的处理,自定义 gesture recognizer #52 3.屏幕渲染原理和绘制,渲染视图时影响性能的主要因素是什么 #48 4.再次回顾了几种不同的事件回调方式的对比 5.有空研究一下 ReactiveCocoa #22 6.相比第一篇文章,这篇文章不是教程,更偏向于理论,理解起来不太直观,但是其中谈到了很多技术点,很值得研究 7.单元测试、UI 自动化测试基本上很少用,不知道国内有多少团队用了 #24