![](/img/trans.png)
[英]subview load from xib,reload view frame, but viewsubviews not change frame
[英]Load view from XIB as a subview of a scrollview
我還是SO和Swift的新手,所以請耐心等待,隨時跳過此問題:-)
在XIB
的awakeFromNib
的主體中,我想將一些視圖作為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
。
我要執行以下操作:
XIB
作為一種“藍圖”,並在我的滾動視圖中多次加載同一視圖; 這可能嗎?
我試圖以這種方式加載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.