gpt4 book ai didi

ios - 从 XIB 加载 View 作为 ScrollView 的 subview

转载 作者:行者123 更新时间:2023-11-28 23:37:11 28 4
gpt4 key购买 nike

我仍然是 SO 和 Swift 的新手,所以请耐心等待并随意跳过这个问题:-)

XIBawakeFromNib 中,我想加载一些 View 作为 UIScrollView 的 subview (基本上,XIB 包含一个 ScrollView 、一个标签和一个按钮)。

如果在循环中我加载动态创建的 View , 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 中,我有一个 ImageView 和一个带有一些标签的堆栈 View 。此 XIB 在 Storyboard中连接到扩展 UIView 的类 SingleEvent

我想做以下事情:

  1. XIB 用作一种“蓝图”,并在我的 ScrollView 中多次加载相同的 View ;
  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
}
}

提前致谢,感谢您的帮助:-)

最佳答案

有许多方法可以从 xibs 加载自定义 View (类)。您可能会发现此方法更容易一些。

首先,像这样创建你的 xib:

enter image description here

请注意,File's Owner 的类别是默认类别 (NSObject)。

相反,将您的自定义类分配给 xib 中的“根” View :

enter image description here

现在,我们的整个自定义 View 类如下所示:

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),
])

}

}

结果是:

enter image description here

还有...这是加载 10 个 SingleEvent View 实例并将它们添加到垂直 ScrollView 的示例:

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)

}

}

}

结果:

enter image description here

关于ios - 从 XIB 加载 View 作为 ScrollView 的 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54628215/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com