簡體   English   中英

從XIB加載視圖作為滾動視圖的子視圖

[英]Load view from XIB as a subview of a scrollview

我還是SO和Swift的新手,所以請耐心等待,隨時跳過此問題:-)

XIBawakeFromNib的主體中,我想將一些視圖作為UIScrollView子視圖加載(基本上, XIB包含滾動視圖,標簽和按鈕)。

如果循環加載我動態創建的視圖,則scrollview可以完美地工作。

 let customView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 150))
 customView.frame = CGRect(x: i*300 , y: 0, width: 300, height: 150)
 customView.translatesAutoresizingMaskIntoConstraints = false
 scrollView.addSubview(customView)

但是我有一個不同的目標。

在另一個XIB我有一個圖像視圖和一個帶有一些標簽的stackview。 XIB在情節SingleEvent中連接到擴展UIView的類SingleEvent

我要執行以下操作:

  1. 使用XIB作為一種“藍圖”,並在我的滾動視圖中多次加載同一視圖;
  2. 向任何實例傳遞一些數據;

這可能嗎?

我試圖以這種方式加載XIB的內容:

 let customView = Bundle.main.loadNibNamed("SingleEvent", owner: self, options: nil)?.first as? SingleEvent

這樣:

let customView = SingleEvent()

第一個使應用程序崩潰,而第二個則沒有問題,但我看不到任何效果(它不會加載任何東西)。

我最新的SingleEvent的內容如下:

 import UIKit

    class SingleEvent: UIView {

        @IBOutlet weak var label:UILabel!
        @IBOutlet weak var imageView:UIImageView!

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

            loadViewFromNib()
        }

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

            loadViewFromNib()
        }

        func loadViewFromNib() -> UIView {
            let myView = Bundle.main.loadNibNamed("SingleEvent", owner: self, options: nil)?.first as! UIView
            return myView
        }
    }

在此先感謝您的幫助:-)

好的我明白了。 該問題實際上可能是loadViewFromNib函數從xib返回UIView的原因,但您並未使用它。
讓我們嘗試這種方式:
1)使您的loadViewFromNib函數靜態

    // Return our SingleEvent instance here  
    static func loadViewFromNib() -> SingleEvent {
            let myView = Bundle.main.loadNibNamed("SingleEvent", owner: self, options: nil)?.first as! SingleEvent
            return myView
        }

2)刪除SingleEvent類中的所有init

3)在需要的地方初始化,如下所示:

let customView = SingleView.loadViewFromNib()

要在視圖內傳遞數據,可以在SingleView類中創建新函數:

func configureView(with dataModel:DataModel) {
   //Set data to IBOutlets here
}

並從外部像這樣使用它:

let customView = SingleView.loadViewFromNib()
let dataModel = DataModel()
customView.configureView(with: dataModel)

有多種方法可以從xib加載定制視圖(類)。 您可能會發現此方法容易一些。

首先,按如下方式創建您的xib:

在此處輸入圖片說明

注意, File's Owner的類是默認的( NSObject )。

而是將自定義類分配給xib中的“ root”視圖:

在此處輸入圖片說明

現在,我們的整個自定義視圖類如下所示:

class SingleEvent: UIView {

    @IBOutlet var topLabel: UILabel!
    @IBOutlet var middleLabel: UILabel!
    @IBOutlet var bottomLabel: UILabel!

    @IBOutlet var imageView: UIImageView!

}

而且,我們沒有創建loadNibNamed(...)到我們的自定義類中,而是創建了一個UIView擴展:

extension UIView {
    class func fromNib<T: UIView>() -> T {
        return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)![0] as! T
    }
}

要加載和使用我們的自定義類,我們可以這樣做:

class FromXIBViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // create an instance of SingleEvent from its xib/nib
        let v = UIView.fromNib() as SingleEvent

        // we're going to use auto-layout & constraints
        v.translatesAutoresizingMaskIntoConstraints = false

        // set the text of the labels
        v.topLabel?.text    = "Top Label"
        v.middleLabel?.text = "Middle Label"
        v.bottomLabel?.text = "Bottom Label"

        // set the image
        v.imageView.image = UIImage(named: "myImage")

        // add the SingleEvent view
        view.addSubview(v)

        // constrain it 200 x 200, centered X & Y
        NSLayoutConstraint.activate([
            v.widthAnchor.constraint(equalToConstant: 200.0),
            v.heightAnchor.constraint(equalToConstant: 200.0),
            v.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            v.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            ])

    }

}

結果:

在此處輸入圖片說明

還有...這是加載10個SingleEvent視圖實例並將其添加到垂直滾動視圖的示例:

class FromXIBViewController: UIViewController {

    var theScrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()

    var theStackView: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .vertical
        v.alignment = .fill
        v.distribution = .fill
        v.spacing = 20.0
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // add the scroll view to the view
        view.addSubview(theScrollView)

        // constrain it 40-pts on each side
        NSLayoutConstraint.activate([
            theScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40.0),
            theScrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -40.0),
            theScrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            theScrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            ])

        // add a stack view to the scroll view
        theScrollView.addSubview(theStackView)

        // constrain it 20-pts on each side
        NSLayoutConstraint.activate([
            theStackView.topAnchor.constraint(equalTo: theScrollView.topAnchor, constant: 20.0),
            theStackView.bottomAnchor.constraint(equalTo: theScrollView.bottomAnchor, constant: -20.0),
            theStackView.leadingAnchor.constraint(equalTo: theScrollView.leadingAnchor, constant: 20.0),
            theStackView.trailingAnchor.constraint(equalTo: theScrollView.trailingAnchor, constant: -20.0),

            // stackView width = scrollView width -40 (20-pts padding on left & right
            theStackView.widthAnchor.constraint(equalTo: theScrollView.widthAnchor, constant: -40.0),
            ])


        for i in 0..<10 {

            // create an instance of SingleEvent from its xib/nib
            let v = UIView.fromNib() as SingleEvent

            // we're going to use auto-layout & constraints
            v.translatesAutoresizingMaskIntoConstraints = false

            // set the text of the labels
            v.topLabel?.text    = "Top Label: \(i)"
            v.middleLabel?.text = "Middle Label: \(i)"
            v.bottomLabel?.text = "Bottom Label: \(i)"

            // set the image (assuming we have images named myImage0 thru myImage9
            v.imageView.image = UIImage(named: "myImage\(i)")

            theStackView.addArrangedSubview(v)

        }

    }

}

結果:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM