简体   繁体   English

子视图在XCode Playground中不起作用

[英]Subview not working in xcode playground

I was trying to add a subview of type UIView to my primary view. 我试图将UIView类型的子视图添加到主视图中。 This does not work accordingly however. 但是,这无法正常工作。 I would think that this should change the screen to red and have a text. 我认为这应该将屏幕更改为红色并显示文本。 Do any of you have an idea what the problem can be? 你们中的任何人都知道问题可能是什么吗?

import UIKit
import Foundation
import PlaygroundSupport

class SecondView : UIView{

  func loadView() {
     let secondViewController = SecondView()
     let label = UILabel()
     label.frame = CGRect(x: 0, y: 335, width: 400, height: 53)

     label.textAlignment = .center
     label.font = UIFont(name: "helveticaneue-ultraLight", size: 40)
     label.text = "Hejsan"
     label.textColor = .white

     secondViewController.addSubview(label)
      print("Test")
}

 }

  class MyViewController : UIViewController {

   //Outlets
   let profileButton = UIButton()

     override func loadView() {
      let view = UIView()

      view.backgroundColor = .green
      print(view.frame)

     let sView = SecondView()
     sView.backgroundColor = .red
     sView.frame = view.frame

     view.addSubview(sView)

     print(sView.frame)

     self.view = view

   }
 }
// Present the view controller in the Live View window

PlaygroundPage.current.liveView = MyViewController()

You are doing so many things wrong :( 您做错了很多事:(

This will run in a playground page, and should be close to what you're going for. 这将在游乐场页面中运行,并且应该与您要的内容接近。 Check the comments to understand what's going on: 查看评论以了解发生了什么:

import UIKit
import Foundation
import PlaygroundSupport

class SecondView : UIView{

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() {

        // create a label
        let label = UILabel()
        // we're going to use auto-layout
        label.translatesAutoresizingMaskIntoConstraints = false

        // add the label to self
        self.addSubview(label)

        // pin the label to leading, trailing and bottom -- all to Zero
        label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0.0).isActive = true
        label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0.0).isActive = true
        label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0.0).isActive = true

        label.textAlignment = .center
        label.font = UIFont(name: "helveticaneue-ultraLight", size: 40)
        label.text = "Hejsan"
        label.textColor = .white

    }

}

class MyViewController : UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // we don't need to create a new view
        //let view = UIView()

        view.backgroundColor = .green

        // create the "SecondView"
        let sView = SecondView()
        // we're going to use auto-layout
        sView.translatesAutoresizingMaskIntoConstraints = false

        // add the new view
        view.addSubview(sView)

        // pin the new view to top, leading and trailing -- all to Zero so it fills this view
        sView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0).isActive = true
        sView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true
        sView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
        sView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true

        sView.backgroundColor = .red

    }

}

// Present the view controller in the Live View window

let vc = MyViewController()
vc.preferredContentSize = CGSize(width: 375, height: 667)
PlaygroundPage.current.liveView = vc

Result: 结果:

在此处输入图片说明

loadView is a UIViewController lifecycle callback method (see docs ). loadView是一个UIViewController生命周期回调方法(请参阅docs )。

Your SecondView is a subclass of UIView that does not define loadView . 您的SecondViewUIView的子类,未定义loadView Therefore the loadView you implemented in SecondView does not get called by the environment. 因此,您在SecondView中实现的loadView不会被环境调用。 You will have to call it explicitly: 您将必须明确地调用它:

let sView = SecondView()
sView.backgroundColor = .red
sView.frame = view.frame

sView.loadView()

view.addSubview(sView)

Moreover, I would recommend to rename it (so that it would confuse with the UIViewController 's loadView . 而且,我建议重命名它(以使其与UIViewControllerloadView混淆。

UPDATE 更新

There are several other errors there. 那里还有其他几个错误。

1 : In your loadView of the second view you are creating a new SecondView and add the label to it. 1 :在第二个视图的loadView中,您将创建一个新的SecondViewSecondView添加标签。 You need to add it to self . 您需要将其添加到self

2 : In loadView of the viewController, you are creating a new view with UIView() which defaults to UIView(frame: CGRect.zero) and then you set sView.frame = view.frame which will make the frame of the second view CGRect.zero too. 2 :在viewController的loadView中,您要使用UIView()创建一个新view ,默认为UIView(frame: CGRect.zero) ,然后设置sView.frame = view.frame ,这将使第二个视图的框架成为CGRect.zero view will be stretched by the UIViewController environment, but the frame of the sView will not be updated. UIViewController环境将扩展view ,但不会更新sView的框架。 There are several options how to do it, but simplest is to initialize the view with a proper frame from the beginning. 有几种方法可以做到这一点,但最简单的方法是从一开始就用适当的frame初始化view Working playground solution: 工作场所解决方案:

import UIKit
import Foundation
import PlaygroundSupport

class SecondView : UIView{

    func loadView() {
        let label = UILabel()
        label.frame = CGRect(x: 0, y: 335, width: 400, height: 53)

        label.textAlignment = .center
        label.font = UIFont(name: "helveticaneue-ultraLight", size: 40)
        label.text = "Hejsan"
        label.textColor = .white

        self.addSubview(label)
        print("Test")
    }

}

class MyViewController : UIViewController {

    //Outlets
    let profileButton = UIButton()

    override func loadView() {
        let view = UIView(frame: UIScreen.main.bounds)

        view.backgroundColor = .green
        print(view.frame)

        let sView = SecondView()
        sView.backgroundColor = .red
        sView.frame = view.frame
        sView.loadView()

        view.addSubview(sView)

        print(sView.frame)

        self.view = view

    }
}
// Present the view controller in the Live View window

PlaygroundPage.current.liveView = MyViewController()

Right way to declare a subview 声明子视图的正确方法

class SecondView: UIView {

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

    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder : aDecoder)
        sharedLayout()
    }

    func sharedLayout()
    {
         let label = UILabel()
         label.frame = CGRect(x: 0, y: 335, width: 400, height: 53)
         label.textAlignment = .center
         label.font = UIFont(name: "helveticaneue-ultraLight", size: 40)
         label.text = "Hejsan"
         label.textColor = .white
         self.addSubview(label)
         print("Test")
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM