【问题标题】:Call a UIKit objects multiple times多次调用一个 UIKit 对象
【发布时间】:2017-04-22 15:38:03
【问题描述】:

我正在以编程方式创建 UIKit 对象,例如 UIButtonUIViewUILabels 等。
有时,我需要多次使用具有相同属性的相同视图。

示例:

如果我需要在textField 周围创建边界线,我会创建UIView 的实例:

let textFieldTopViewSeparator: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.gray
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

然后,设置它的约束:

func textFieldTopViewSeparatorConstraints() {
    textFieldTopViewSeparator.heightAnchor.constraint(equalToConstant: 1).isActive = true
    textFieldTopViewSeparator.topAnchor.constraint(equalTo: self.textField.topAnchor).isActive = true
    textFieldTopViewSeparator.widthAnchor.constraint(equalTo: self.textField.widthAnchor).isActive = true
    textFieldTopViewSeparator.centerXAnchor.constraint(equalTo: self.textField.centerXAnchor).isActive = true
}

并拨打viewDidLoad()

override func viewDidLoad() {
    super.viewDidLoad()

    self.view.addSubview(textFieldTopViewSeparator)
    textFieldTopViewSeparatorConstraints()
}

这只会在textField的顶部创建一个边框,然后要创建一个底部,我需要创建另一个视图,给它约束,然后在viewDidLoad()中再次调用它们

所以我的问题是,有没有办法只创建一个视图实例并在不同的约束下多次使用它?即使使用不同的方式来创建视图。

【问题讨论】:

  • 如果要添加两个标签,则需要创建两个UILabel 实例。
  • 但是在 1 个视图控制器中创建相同实例可能会产生 6 次冗余。
  • 为什么?您需要唯一的实例。一个视图只能有一个框架。
  • “有没有办法只创建一个视图实例并在不同的约束下多次使用它?” - 没有。
  • “即使使用不同的方式来创建视图。” - 不可以。给定视图在任何给定时间只能出现一次。时期。讨论完毕。您想要两个标签、两个分隔视图,还是同时需要两个“任意”视图?然后您必须创建两个标签、分隔视图或“任何”实例。

标签: ios uiview uibutton uikit


【解决方案1】:

在我看来,您只想在 UITextField 的顶部和底部添加一个 border。你正在接近这个错误。我会建议一个不同的解决方案。

Objective-C 代码:

CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0.0f, self.frame.size.height - 1, self.frame.size.width, 1.0f);
bottomBorder.backgroundColor = [UIColor blackColor].CGColor;
[myTextField.layer addSublayer:bottomBorder];

Swift 代码:

var bottomBorder = CALayer()
bottomBorder.frame = CGRectMake(0.0, textField.frame.size.height - 1, textField.frame.size.width, 1.0);
bottomBorder.backgroundColor = UIColor.blackColor().CGColor
textField.layer.addSublayer(bottomBorder)

你也可以这样做顶线。

但是“Aviel Gross" 的回答应该最适合您的需求:

class FramedTextField: UITextField {

    @IBInspectable var linesWidth: CGFloat = 1.0 { didSet{ drawLines() } }

    @IBInspectable var linesColor: UIColor = UIColor.blackColor() { didSet{ drawLines() } }

    @IBInspectable var leftLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var rightLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var bottomLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var topLine: Bool = false { didSet{ drawLines() } }



    func drawLines() {

        if bottomLine {
            add(CGRectMake(0.0, frame.size.height - linesWidth, frame.size.width, linesWidth))
        }

        if topLine {
            add(CGRectMake(0.0, 0.0, frame.size.width, linesWidth))
        }

        if rightLine {
            add(CGRectMake(frame.size.width - linesWidth, 0.0, linesWidth, frame.size.height))
        }

        if leftLine {
            add(CGRectMake(0.0, 0.0, linesWidth, frame.size.height))
        }

    }

    typealias Line = CGRect
    private func add(line: Line) {
        let border = CALayer()
        border.frame = line
        border.backgroundColor = linesColor.CGColor
        layer.addSublayer(border)
    }

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

}

您可以在此处找到有关此主题的更多信息:UITextField Only Top And Bottom Border

【讨论】:

    【解决方案2】:

    UIView 只允许有一个父视图。所以不,不可能多次使用UIView

    Apple Documentation of addSubview()

    视图只能有一个超级视图。如果视图已经有一个父视图并且该视图不是接收者,则此方法会在将接收者设为新的父视图之前删除先前的父视图。

    【讨论】:

    • 这并没有解决问题,因为所有有问题的视图都具有相同的父级。
    • ?我不明白你的评论。那么如何添加到父级是使用的视图?每次您将其添加到另一个视图时(如果您想显示它,您必须这样做),之前的连接就会丢失。所以它在我看来完全回答了这个问题。
    • OP 想要创建一个视图的单个实例,然后将其多次添加到单个父视图中。当然这是不可能的。但是您的回答暗示这是不可能的,因为一个视图不能有多个父级。在 OP 的情况下,这不是限制因素,因为他们已经计划只有一个父视图。但是您仍然不能多次将单个视图添加到单个父级。
    • 在我看来是一样的。一个视图只能有一个框架,更改它并且它在其他地方,简单的逻辑。因此,再次添加它是我考虑的唯一选择。但谁在乎呢,这个问题已经回答了。我走了。
    猜你喜欢
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多