在视图代码类文件中引用超级视图

Posted

技术标签:

【中文标题】在视图代码类文件中引用超级视图【英文标题】:Referencing superview inside of view code class file 【发布时间】:2018-03-21 20:59:26 【问题描述】:

我目前正尝试在Swift 中以编程方式学习约束和样式。我还试图通过拆分与“样式”相关的代码来维护干净和模块化的代码。

我只是有我的LoginViewController

import UIKit

class LoginViewController: UIViewController 

    var loginView: LoginView!

    override func viewDidLoad() 
        super.viewDidLoad()

        loginView = LoginView(frame: CGRect.zero)
        self.view.addSubview(loginView)

        // AutoLayout
        loginView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets.zero, excludingEdge: .bottom)
    

    override var preferredStatusBarStyle: UIStatusBarStyle 
        return .lightContent
    


然后我的LoginView

import UIKit

class LoginView: UIView 
    var shouldSetupConstraints = true

    var headerContainerView: UIView!

    override init(frame: CGRect) 
        super.init(frame: frame)

        // Header Container View
        headerContainerView = UIView(frame: CGRect.zero)
        headerContainerView.backgroundColor = UIColor(red:0.42, green:0.56, blue:0.14, alpha:1.0) // #6B8E23
        headerContainerView.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(headerContainerView)

        headerContainerView.topAnchor.constraint(equalTo: self.superview!.topAnchor)

    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

    override func updateConstraints() 
        if(shouldSetupConstraints) 
            // AutoLayout constraints
            shouldSetupConstraints = false
        
        super.updateConstraints()
    

我卡住的地方只是简单地尝试将这个headerContainerView 添加到我的superview 的顶部。我希望能够添加它,使其自身固定在superview 的顶部、左侧和右侧,并且只有superview's 高度的1/3。我继续尝试引用superview,但没有成功,我在互联网上找不到帮助我理解的解决方案。关于如何完成此任务的任何建议?

感谢您抽出时间回复回复。

注意:我确实开始使用PureLayout,这真的很好。但是,我是一个喜欢了解幕后发生的事情或至少如何在基本级别编写代码的人。你可以看到我在LoginViewController 中使用了PureLayout 函数,但我希望改变它。我更喜欢不添加第三方库的解决方案。

【问题讨论】:

尝试使用SnapKit,它更灵活。 有什么理由在两个地方做布局吗?我看到边缘是在 VC 级别完成的,顶部锚点是在 LoginView 内完成的。我鼓励你们两个使用以下准则: 视图中的自动布局代码只能引用自身或其后代(不能引用父视图)。在这种情况下,把所有的布局代码放在VC里面 我也没有看到任何与视图高度相关的代码。 您是否认为这是构建 ios 应用程序的糟糕架构?我刚刚看到很多关于 MVC 的讨论,但在 iOS 中,它似乎真的只是 MV,因为所有代码都进入了VC。这导致你拥有一个巨大的 VC。 VC不应该用于功能而不是影响应用程序视图的代码吗?这就是为什么我试图从一个分裂的场景中解决这个问题。我觉得它稍微干净一些。但我是新手,感谢您的洞察力。 【参考方案1】:

自定义UIView 类中的selfheaderContainerView 的父视图,所以,你可以添加这个,另外我建议先学习约束,不要使用3rd 方库来完全理解这个概念,因为你会学到一个很多从看到冲突和其他事情,一旦完成,转移到图书馆

override init(frame: CGRect) 
    super.init(frame: frame)

    // Header Container View
    headerContainerView = UIView(frame: CGRect.zero)
    headerContainerView.backgroundColor = UIColor(red:0.42, green:0.56, blue:0.14, alpha:1.0) // #6B8E23
    headerContainerView.translatesAutoresizingMaskIntoConstraints = false

    self.addSubview(headerContainerView)
    headerContainerView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    headerContainerView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
    headerContainerView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
    headerContainerView.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier:1.0/3.0, constant: 0.0).active = true


//登录视图布局

override func viewDidLoad() 
    super.viewDidLoad()

    loginView = LoginView(frame: CGRect.zero)
    self.view.addSubview(loginView)
    loginView.translatesAutoresizingMaskIntoConstraints = false
    loginView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    loginView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    loginView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
    loginView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

【讨论】:

学习约束其实是我想做的。我最初使用PureLayout,但想自己学习约束。我已尝试实施您的解决方案。但是,当我Build/Run 应用程序时,屏幕是黑色的。关于为什么会这样的任何想法? 因为 loginView = LoginView(frame: CGRect.zero) 有零帧 改变这种情况的适当方法是什么?我试图添加`LoginView(frame: CGReact(x:0,y:0,width:view.bounds.width,heigth:view.bounds.height))。但没有成功。 这帮助很大。我正在了解为什么以及何时需要引用 self 以及在这种情况下 self 是什么。感谢您的帮助!【参考方案2】:
headerContainerView.snp.makeConstraints  (make) in
        make.top.equalTo(self)
        make.leading.and.trailing.equalTo(self)
        make.height.equalTo(self.frame.height/3)
    

SnapKit。

【讨论】:

【参考方案3】:

使用 SnapKit,您可以执行以下操作:

override func viewDidLoad() 
    super.viewDidLoad()

    loginView = LoginView(frame: CGRect.zero)
    self.view.addSubview(loginView)

    // AutoLayout
    loginView.snp.makeConstraints  (make) in
        make.left.equalTo(view.snp.left)
        make.right.equalTo(view.snp.right)
        make.top.equalTo(view.snp.top)
        make.height.equalTo(view.snp.height).multipliedBy(1/3)
    

【讨论】:

以上是关于在视图代码类文件中引用超级视图的主要内容,如果未能解决你的问题,请参考以下文章

ViewBinding用法

Android ViewBinding使用详解

如何从自定义表格视图单元类中获取对表格视图控制器的引用

Android View Binding使用详解

膨胀内部类视图时出错

如何从 iPhone 中的子视图更新超级视图 UILabel 文本?