自动布局的一个小坑

最近在用Swift下的SnapKit写一个登录注册界面,写完调试时出现了一个奇葩的问题,具体是这样:

登录的placeholder明显在后面,而密码的则无问题。我仔细对比了两个创建输入框的代码:

   lazy var usernameLabel :ROBaseInputView = {
        var usernameLabel = ROBaseInputView.init(title: "用户名", placeholder: "请输入用户名")
        usernameLabel.addRule(rule: { (object) -> (Bool, String, AnyObject) in
            guard let text = (object as! ROBaseInputView).textfield.text else{ return (false, "请输入用户名", object)   }
            if text.characters.count < 3 {
                return (false, "用户名必须大于3个字母或数字", object)
            }
            let rx = "[A-Z0-9a-z]{4,10}"
            return ((text =~ rx), "用户名必须为数字或字母", object)
        })
        return usernameLabel
    }()
    
    lazy var passwordLabel :ROBaseInputView = {
        var passwordLabel = ROBaseInputView.init(title: "密码", placeholder: "请输入密码")
        passwordLabel.textfield.isSecureTextEntry = true
        passwordLabel.addRule(rule: { (object) -> (Bool, String, AnyObject) in
            guard let text = (object as! ROBaseInputView).textfield.text else{ return (false, "请输入密码", object)   }
            if text.characters.count < 6 {
                return (false, "密码必须大于6个字母或数字", object)
            }
            let rx = "[A-Z0-9a-z]{6,10}" 
            return ((text =~ rx), "密码必须为数字或字母", object)
        })
        return passwordLabel
    }()

这明明是一毛一样好不好,完全让我彻底懵了逼,我将无关的代码删除,只是保持这两个InputView的存在,发现问题依旧,我只能将passwordLabel的布局也依赖于icon图片(usernameLabel的布局是依赖于icon图片,usernameLabel和passwordLabel仅仅在此处不同),这时就出现了这个问题了,我发现,只要在相对布局中引用ImageVIew,那就有问题,对Self.view相对布局则没有问题!

我天真的以为,这是Snapkit的bug,故更新SnapKit.

问题依旧!怎么办,我也很绝望啊。重新review代码,这是布局图:

这是ROBaseInputView的代码内部空间布局的关键一段。

	    self.addSubview(textfield)
	    self.addSubview(title)

        
        title.snp.makeConstraints { (make) in
            make.left.centerY.equalTo(self)
        }
        
        textfield.snp.makeConstraints { (make) in
            make.left.equalTo(title.snp.right).offset(15)
            make.right.bottom.equalTo(self)
            make.top.equalTo(self).offset(5)
        }

我的想法是,title可以根据前面的名字长短自动伸缩,而textfield只要接在title的后面并且衍生到最后面就可以了。看似这个想法很好,但是,title和textfield的布局完全没有指定width,这就造成了之前的问题,Snapkit可以随机(或者是依据参考的对象来确定)指定两个控件的分界线!

这居然是个随机bug,但是看起来就不是那么一回事啊。。。

解决办法想必大家都应该知道了,就是利用布局的优先级。将它在创建的时候就确定一个低优先级的布局,指定宽度为1,这样子textfield就向前贪婪布局,而由于之后再指定字体的宽度,这又是一个高优先级的操作,所以就只会把textfield向后推动可容纳字体的宽度,这样就可以解决了。实际上就是一行代码:

  title.snp.makeConstraints { (make) in
            make.left.centerY.equalTo(self)
            make.width.equalTo(1).priority(100)
  }

看来我写代码还太心浮气躁了。

最近的文章

iOS下关于屏幕旋转的一二件小事

控制方向一般的应用,只会支持竖屏正方向一个方向,支持多个屏幕方向的应用还是比较少的。最近在我的项目中,涉及到视频的旋转,跟这个屏幕方向接触比较多,根据网上的几个测试例子,结合项目做了这个总结。怎么控制屏幕方向在 iOS 的应用中,有多种方式可以控制界面的屏幕方向,有全局的,有针对 UIWindow 中界面的控制,也有针对单个界面。单个界面控制单个界面控制主要是指某个ViewController的方向控制。这里要注意,要在ViewController的跟控制器加上方法,一般来说,如果是pus...…

继续阅读
更早的文章

IOS下的图片模糊化模糊化

起因最近在模仿苹果端网易云音乐客户端,在进入音乐那里特别喜欢图片毛玻璃的效果,这个看了下网上,有开源的设计,但是封装的很蛋疼,而且最恶心的是,为啥接口和实现不分开呢。基于这点,我对实现进行了封装。接口初始化并设置蒙版的颜色-(ANBlurredImageView *)initWithBlurAmount:(CGFloat)amount withTintColor:(UIColor *)color; 默认的模糊化设置-(void)blurredImageViewDefault; 默认的清晰化...…

继续阅读