ios - 分离约束和 UI 元素(UIView、UIButton、UITextField 等)声明以分离 swift 文件

标签 ios swift xcode optimization uiview

我看过相关文章,但没有一篇解决类似问题。我想分开我的 View 代码,例如exampleView.swift 我的 UI 组件放在一个单独的文件中,我对它们应用的约束放在单独的文件中。

exampleView.swift

import UIKit

class LoginController: UIViewController {

let inputContainerView: UIView = {
    var view = UIView()
    view.backgroundColor = UIColor.white
    view.translatesAutoresizingMaskIntoConstraints = false
    view.layer.cornerRadius = 5
    view.layer.masksToBounds = true

    return view
}()
let loginRegisterButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
    button.setTitle("Register", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(registerTapped), for: .touchUpInside)

    return button
}()
let nameTextField: UITextField = {
    var tf = UITextField()
    tf.placeholder = "Name"
    tf.translatesAutoresizingMaskIntoConstraints = false

    return tf
}()
let nameSeparatorView: UIView = {
    var view = UIView()
    view.backgroundColor = UIColor(r: 220, g: 220, b: 220 )
    view.translatesAutoresizingMaskIntoConstraints = false

    return view
}()
let emailTextField: UITextField = {
    var tf = UITextField()
    tf.placeholder = "Email"
    tf.translatesAutoresizingMaskIntoConstraints = false

    return tf
}()
let emailSeparatorView: UIView = {
    var view = UIView()
    view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
    view.translatesAutoresizingMaskIntoConstraints = false

    return view
}()
let passwordTextField: UITextField = {
    var tf = UITextField()
    tf.placeholder = "Password"
    tf.translatesAutoresizingMaskIntoConstraints = false
    tf.isSecureTextEntry = true

    return tf
}()
let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "Dragon")
    imageView.translatesAutoresizingMaskIntoConstraints = false
    return imageView
}()
override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor(r: 61, g: 91, b: 151)
    view.addSubview(inputContainerView)
    view.addSubview(loginRegisterButton)
    view.addSubview(profileImageView)
    setupInputContainerView()
    setupLoginRegisterButton()
    setupProfileImageView()
}
//MARK: - Constraints
func setupProfileImageView(){
    //need x, y, width , height
    profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    profileImageView.bottomAnchor.constraint(equalTo: inputContainerView.topAnchor, constant: -12).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: 150).isActive = true
    profileImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true
}
func setupInputContainerView(){
    // need x, y, width and height constraint
    inputContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    inputContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    inputContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
    inputContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true

    inputContainerView.addSubview(nameTextField)
    inputContainerView.addSubview(nameSeparatorView)
    inputContainerView.addSubview(emailTextField)
    inputContainerView.addSubview(emailSeparatorView)
    inputContainerView.addSubview(passwordTextField)

    // need x, y, width , height constraints
    nameTextField.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor, constant: 12).isActive = true
    nameTextField.topAnchor.constraint(equalTo: inputContainerView.topAnchor).isActive = true
    nameTextField.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    nameTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: 1/3).isActive = true

    // need x, y, width, height constraints
    nameSeparatorView.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor).isActive = true
    nameSeparatorView.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true
    nameSeparatorView.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    nameSeparatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

    // need x, y, width , height constraints
    emailTextField.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor, constant: 12).isActive = true
    emailTextField.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true
    emailTextField.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    emailTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: 1/3).isActive = true

    // need x, y, width, height constraints
    emailSeparatorView.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor).isActive = true
    emailSeparatorView.topAnchor.constraint(equalTo: emailTextField.bottomAnchor).isActive = true
    emailSeparatorView.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    emailSeparatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

    passwordTextField.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor, constant: 12).isActive = true
    passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor).isActive = true
    passwordTextField.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    passwordTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: 1/3).isActive = true
}
func setupLoginRegisterButton(){
    // need x, y, width and height constraint
    loginRegisterButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    loginRegisterButton.topAnchor.constraint(equalTo: inputContainerView.bottomAnchor, constant: 12).isActive = true
    loginRegisterButton.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
    loginRegisterButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

//    loginRegisterButton.addTarget(self, action: #selector(registerTapped), for: .touchUpInside)

}
override var preferredStatusBarStyle: UIStatusBarStyle{
    get{
        return .lightContent
    }
}
//MARK: Actions
@objc func registerTapped(){
    print("Registered")
}
}
extension UIColor{
    convenience init(r: CGFloat, g: CGFloat, b: CGFloat) {
        self.init(red: r/255, green: g/255, blue: b/255, alpha: 1.0)
   }
}

问题:

我想将以下类型的 View 声明分离到单独的文件中,以便我可以将参数传递给它并生成(作为返回)所需的 UI 组件(例如 View 、按钮、文本字段、行)。

let inputContainerView: UIView = {
    var view = UIView()
    view.backgroundColor = UIColor.white
    view.translatesAutoresizingMaskIntoConstraints = false
    view.layer.cornerRadius = 5
    view.layer.masksToBounds = true

    return view
}()

我还想将约束分离到一个单独的文件中,这样我就可以通过将所需的约束作为参数传递来调用和应用任何约束。因此,以下类型的约束将进入一个单独的外部文件。我们可以像在 web CSS 属性中那样传递定位约束(例如 margin: 4px 2px 0 4px 并且可以是相对元素 reference 作为参数,所以约束可以是需要时引用任何其他元素应用。)

func setupProfileImageView(){
    //need x, y, width , height
    profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    profileImageView.bottomAnchor.constraint(equalTo: inputContainerView.topAnchor, constant: -12).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: 150).isActive = true
   profileImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true
}

这样,当我将这些声明和操作分离到单独的 swift 文件中时,我的 View 代码将缩减到几行,即减少 70%。

最佳答案

好的,我认为您想将单个 VC 文件代码分类到不同的文件中,以便于管理。

首先,请记住,我不知道您的代码实际上在做什么。我只是在解释如何创建扩展文件以及如何使用它。

扩展文件 帮助您将单个文件代码管理到多个文件中。您可以使用变量并使用 self 调用函数.

注意:您不能在扩展文件中声明变量。如果您尝试,您会遇到以下错误。

enter image description here

如何创建扩展文件

  1. 在您的项目中创建新文件。

enter image description here

  1. 选择 swift 文件。

enter image description here

  1. 以格式保存 -> <your_VC_Name>+<File_purpose>

your_VC_Name 是您为其创建扩展的 VC。

File_purpose 是创建扩展的目的或规范。例如。对于约束乐趣,我使用了 Constraints如果我想要 Web 服务的扩展,那么我将其命名为 webservices。

不要忘记添加 +介于两者之间。

以上描述只是一种命名约定,大家可以很容易理解,因为它是标准格式。

enter image description here

如何使用扩展:

  1. 使用下面的代码使您的文件成为扩展文件。

    import Foundation
    
    extension LoginController {
    
    }
    
  2. 现在从 LoginController 中删除你的函数并粘贴到扩展文件中。

    extension LoginController {
       func myFunc() {
        }
    }
    
  3. 像这样调用你的函数

    self.myFunc()
    

注意:您可以使用 self 来使用任何函数不管你的函数写在哪里。但是您可以在扩展文件中声明任何变量。

关于ios - 分离约束和 UI 元素(UIView、UIButton、UITextField 等)声明以分离 swift 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113358/

相关文章:

iphone - 我们如何从iPhone应用程序中找到我们的instagram用户ID和关注者列表以及他们的用户ID

ios - 在 SwiftUI 中切换更改后更新数组

ios - swift 2 : Email Cancel Button Stops Working After Second Try on a Table View

ios - 如何在大型导航栏上使用图像作为标题?

ios - 没有箭头无法定位弹出窗口

Swift- 动画 CAshapeLayer 描边颜色

ios - 尝试将 AlamoFire JSON 响应映射到类并接收 "Fatal Error: Unexpectedly found nil while unwrapping optional"

swift - 更改属性其他功能

ios - 如何在 Xcode6 的 Storyboard上重置特定大小的类数据?

ios - 如何在 iOS Xcode UI 测试用例中启动系统应用程序