V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
banxi1988
V2EX  ›  iDev

简单的基于组合的 Custom View (Swift) 示例

  •  
  •   banxi1988 ·
    banxi1988 · 2015-06-07 01:29:06 +08:00 · 2588 次点击
    这是一个创建于 3448 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单的基于组合的Custom View 示例 - 一个前面带一个 Icon 的 TextField的简单实现

    需求

    一个项目中很多地方都用到这种一个Icon 后面跟着一个TextField的 UI. 因为 Xcode 不支持这种界面上的重用.
    而且就是是Copy and Paste也是有问题的,因为Copy进,View的约束并不会跟着走
    为了避免重复劳动 ,就只要写一个简单的Custom View来实现了.

    代码分析:

    完整源代码见: https://gist.github.com/banxi1988/d31c7a41f29e7ddca728

    1. @IBDesignable - 自定义View的类声明没有此属性的话,Interface Builder 中的预览界面是显示不出来的.
    2. 可以通过prepareForInterfaceBuilder()方法来设置,只在开发时可用的初始值, 注意在开发时的,资源加载需要多写的代码.如:
    override func prepareForInterfaceBuilder() {
            super.prepareForInterfaceBuilder()
            let bundle = NSBundle(forClass: self.dynamicType)
            let image = UIImage(named: "icon_locate", inBundle: bundle, compatibleWithTraitCollection: self.traitCollection)
            iconImageView.image = image
            textField.text = "大学英语四级"
            backgroundColor = UIColor.lightGrayColor()
        }
    
    1. 注意重写 instrinsicContentSize() 一般的实现逻辑的,遍历,组合,比较,求和.
    override func intrinsicContentSize() -> CGSize {
            let iconSize = iconImageView.intrinsicContentSize()
            let textSize = textField.intrinsicContentSize()
    
            let width  = padding.left + iconSize.width + iconPadding + textSize.width + padding.right
            let height = padding.top + max(iconSize.height, textSize.height) + padding.bottom
            return CGSize(width: width, height: height)
        }
    
    1. 设置AutoLayout约束时,值得注意:
      4.1 除非确实需要,不要忘记调用 iconImageView.setTranslatesAutoresizingMaskIntoConstraints(false)
      4.2 设置好contentHuggingPriority,和 contentResistancePriority
      如这里,在整个UI控制伸长时,先让textField变长
      textField.setContentHuggingPriority(240, forAxis: UILayoutConstraintAxis.Horizontal)

    2. 当组合中的子控件的内容发生了变化,正确做法是应该调用:
      invalidateIntrinsicContentSize()

    3. @IBInspectable 属性目前不建议使用,用一次卡一次
      如果取消不用了,记得将IB中控件属性的这些自定义属性,删除.

    PS:
    问: 标题是基于组合的Custom View 那还有基于其他的吗?
    答: 有,还有基于继承,然后主要是 自定义 drawRect 方法,或者自定义 CALayer
    当然,更多是两者都基于.

    希望对大家有用.

    7 条回复    2015-06-09 00:58:31 +08:00
    ruandao
        1
    ruandao  
       2015-06-07 03:15:53 +08:00
    楼主,请教下,如何设置标准的ImageView的控件(符合contentMode的控件, 默认ImageView 的intrinsicContentSize返回的是Image的size, 但是,当ImageView的宽度受限的时候,intrinsicContentSize 并没有根据contentMode 返回对应的值)

    xib 里面的imageView 的intrinsicContentSize 里面默认返回的是 image的size, 这样,导致当宽度达不到image的宽度的时候,高度扔进使用image的高度

    恩, 我做了个简单的 demo 来演示

    https://github.com/ruandao/kkk


    黄色是需要去除的
    谢谢
    banxi1988
        2
    banxi1988  
    OP
       2015-06-07 08:38:31 +08:00   ❤️ 1
    @ruandao 你的demo我看了.
    imageView 返回的 instrinsicContentSize 返回的是图片的大小,这没有错.
    如果你想限制imageView的frame 大小, 你可以设置宽度及高度的约束啊.
    blank_dlh
        3
    blank_dlh  
       2015-06-07 11:05:35 +08:00   ❤️ 1
    不是能设置 UITextField 的 leftView 吗 - -
    ruandao
        4
    ruandao  
       2015-06-07 12:39:16 +08:00
    @banxi1988
    恩, 但是宽度约束不确定,是由周围的label 确定的
    banxi1988
        5
    banxi1988  
    OP
       2015-06-07 23:11:04 +08:00
    @blank_dlh 谢谢提醒,我突然想起来还有这个,一时忘记了.
    不过,在我界面需要下使用leftView是无法实现的.
    首先对于icon的位置没有提供接口. 而且leftView 是内联的. 在某些情况下, leftView 应该会是更好的选择.
    banxi1988
        6
    banxi1988  
    OP
       2015-06-08 08:27:23 +08:00   ❤️ 1
    @ruandao 宽度约束是动态的确实的,那你可以使用图片的宽高比的约束. 如果是在Inteface Builder中叫
    Aspect Ratio
    ruandao
        7
    ruandao  
       2015-06-09 00:58:31 +08:00
    @banxi1988

    恩, 谢谢 倒是没意识到这个
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3517 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:45 · PVG 12:45 · LAX 20:45 · JFK 23:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.