2017-08-02 57 views
0

我试图构建(编程)新视图并使用IBDesignable属性来简化此过程,并在故事板中显示视图而不是白色矩形。带动态约束的IBDesignable视图:渲染时放错位置的孩子

这里有两个子视图:UILabelUIImageView。我动态将其添加到父视图,并为他们夫妇的约束:

import UIKit 

@IBDesignable 
class ChoiceView: UIView { 

    enum ChoiceState { 
     case empty, chosen 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setupViewForState(.empty) 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setupViewForState(.empty) 
    } 

    override func awakeFromNib() { 
     super.awakeFromNib() 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 
    } 

    private func setupViewForState(_ state: ChoiceState) { 
     guard case .empty = state else { return } // single case for now 

     let placeholder = UILabel() 
     let choiceImage = UIImageView(image: UIImage(named: "plus_small")) 
     placeholder.text = "None" 
     placeholder.textAlignment = .right 
     choiceImage.contentMode = .center 

     let constraintFormats = [ 
      "H:|-0-[placeholder]-10-[choice(50)]-0-|", 
      "V:|-0-[placeholder]-0-|", 
      "V:|-0-[choice]-0-|" 
     ] 

     let views = ["placeholder": placeholder, "choice": choiceImage] 

     translatesAutoresizingMaskIntoConstraints = false 
     placeholder.translatesAutoresizingMaskIntoConstraints = false 
     choiceImage.translatesAutoresizingMaskIntoConstraints = false 
     addSubview(placeholder) 
     addSubview(choiceImage) 

     let constraints = constraintFormats.flatMap { 
      NSLayoutConstraint.constraints(
       withVisualFormat: $0, 
       options: .directionLeadingToTrailing, 
       metrics: nil, 
       views: views) 
     }   

     NSLayoutConstraint.activate(constraints) 
    } 

} 

这些都不是很完美,但至少 - 显示在模拟器: cell in simulator

但是当我重装意见在故事板建设者,我看到: cell in storyboard

正如你所看到的,约束不是在故事板执行,图像不显示。你知道如何解决这个问题吗?或者,是否有可能在故事板和模拟器中获得相同的图像?


解决方案:请看看@DonMag答案。它允许看到我期待的结果(见附图)。

enter image description here

+0

由于IB是*设计时*工具,你不能指望*码*在对其进行处理。所以,不,这是不可能的。 – dfd

+0

我明白了,但你看,标签显示正确,标题设置在代码中。因此,我可以对'UIImage'做同样的事情。 – devforfu

+0

@devforfu你检查了我的答案吗? –

回答

1

不要为满足各种设计视图本身设置translatesAutoresizingMaskIntoConstraints = false

let views = ["placeholder": placeholder, "choice": choiceImage] 

    // don't do this one 
    //translatesAutoresizingMaskIntoConstraints = false 
    placeholder.translatesAutoresizingMaskIntoConstraints = false 
    choiceImage.translatesAutoresizingMaskIntoConstraints = false 
    addSubview(placeholder) 
    addSubview(choiceImage) 

而且,看到你的IB“选择”图像:

let theBundle = Bundle(for: type(of: self)) 
    let choiceImage = UIImageView(image: UIImage(named: "plus_small", in: theBundle, compatibleWith: self.traitCollection)) 
    // 
    //let choiceImage = UIImageView(image: UIImage(named: "plus_small")) 
    ... 
+0

完全有效的解决方案。图像和标签都能正确显示和对齐。 – devforfu