如何将额外参数传递给链接到 XIB 文件的自定义 UIView?
How to pass in extra arguments to a custom UIView that is linked to a XIB file?
我目前有一个名为 MovieCard 的数据类型,它包含有关电影的所有数据,它需要显示在卡片上,也就是 UIView。我创建了一个名为 MovieCardView 的自定义 UIView class,并通过文件所有者将其链接到 XIB 文件。 MovieCardView 包含一些标签和一个图像视图。
我的问题是,我必须在 MovieCardView 文件中写入什么(我对捆绑加载感到困惑)以及如何将电影卡传递给 MovieCardView?我希望 MovieCardView 利用电影卡中的数据为 MovieCardView 中的标签和 ImageView 设置一些值。
这是我的视图控制器中的内容,也是我希望发生的事情
func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let movieCard = cards[index]
return MovieCardView(movieCard: movieCard)
}
我当前的视图文件如下所示
class MovieCardView: UIView {
@IBOutlet var moviePoster: UIImageView!
@IBOutlet var movieTitle: UILabel!
@IBOutlet var movieYear: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
Bundle.main.loadNibNamed("MovieCardView", owner: self, options: nil)
}
}
我不确定如何修改代码以允许我从我的视图控制器传入 movieCard 并以编程方式将 IBOutlet 设置为我的 movieCard 的某些属性。我也根本不想以编程方式更改框架。任何帮助,将不胜感激。谢谢!
更新
我尝试了以下
import UIKit
import Kingfisher
class MovieCardView: UIView {
@IBOutlet weak var poster: UIImageView!
let movieCard: MovieCard
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
Bundle.main.loadNibNamed("MovieCardView", owner: self, options: nil)
guard let posterString = movieCard.poster_path else {
return
}
let urlString = "https://image.tmdb.org/t/p/w300" + posterString
guard let posterImageURL = URL(string: urlString) else {
return
}
poster.kf.setImage(with: posterImageURL)
}
}
我收到错误提示 属性 'self.movieCard' not initialized at super.init call for override init and required init methods。我该如何纠正这个问题?谢谢!
I am getting errors saying Property 'self.movieCard' not initialized at super.init call for both override init and required init methods.
Swift 编译器会阻止您创建未完全初始化的对象,因此在初始化超级 class 之前,您需要为 class 的对象提供值属性。
How do I rectify this?
您需要在调用 super.init
之前在初始化程序中为 movieCard
属性 提供一个值,或者使 movieCard
可选,以便编译器允许你把它留到以后再设置。例如,您可以将声明更改为:
var movieCard = MovieCard()
只给它一个空的 MovieCard
实例,然后将其设为 var
以便您以后可以更改它。您还可以标记变量 lazy
,这样除非您尝试访问 属性:
的值,否则实际上不会创建空的 MovieCard
lazy var movieCard = MovieCard()
Copy/paste将以下代码添加到您的项目中。
public extension UIView {
class var bundle: Bundle { Bundle(for: self) }
class var identifier: String { String(describing: self) }
class var nibName: String { identifier }
class var nib: UINib { UINib(nibName: nibName, bundle: bundle) }
class func instantiateFromNib<T: UIView>() -> T {
return nib.instantiate(withOwner: nil, options: [:])[0] as! T
}
}
现在您可以在想要实例化您的自定义时执行此操作 UIView
。
let view: MovieCardView = MovieCardView.instantiateFromNib()
从 MovieCardView
开始,您可以删除所有 init
覆盖和 commonInit
方法。添加一种这样的方法。
func populateMovieCard(_ movieCard: MovieCard) {
// populate your details on to UI here
}
import UIKit
import Kingfisher
class MovieCardView: UIView {
@IBOutlet weak var poster: UIImageView!
var movieCard: MovieCard? = nil
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup(_ movieCard: MovieCard) {
self.movieCard = movieCard
guard let posterString = movieCard.poster_path else {
return
}
let urlString = "https://image.tmdb.org/t/p/w300" + posterString
guard let posterImageURL = URL(string: urlString) else {
return
}
poster.kf.setImage(with: posterImageURL)
}
}
// from controller when you initialising customview call this function from there like below
func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let movieCard = cards[index]
guard let customView = Bundle.main.loadNibNamed("MovieCardView", owner: nil, options: nil) as? MovieCardView else { return UIView() }
customView.setUp(movieCard);
return customView
}
我目前有一个名为 MovieCard 的数据类型,它包含有关电影的所有数据,它需要显示在卡片上,也就是 UIView。我创建了一个名为 MovieCardView 的自定义 UIView class,并通过文件所有者将其链接到 XIB 文件。 MovieCardView 包含一些标签和一个图像视图。
我的问题是,我必须在 MovieCardView 文件中写入什么(我对捆绑加载感到困惑)以及如何将电影卡传递给 MovieCardView?我希望 MovieCardView 利用电影卡中的数据为 MovieCardView 中的标签和 ImageView 设置一些值。
这是我的视图控制器中的内容,也是我希望发生的事情
func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let movieCard = cards[index]
return MovieCardView(movieCard: movieCard)
}
我当前的视图文件如下所示
class MovieCardView: UIView {
@IBOutlet var moviePoster: UIImageView!
@IBOutlet var movieTitle: UILabel!
@IBOutlet var movieYear: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
Bundle.main.loadNibNamed("MovieCardView", owner: self, options: nil)
}
}
我不确定如何修改代码以允许我从我的视图控制器传入 movieCard 并以编程方式将 IBOutlet 设置为我的 movieCard 的某些属性。我也根本不想以编程方式更改框架。任何帮助,将不胜感激。谢谢!
更新 我尝试了以下
import UIKit
import Kingfisher
class MovieCardView: UIView {
@IBOutlet weak var poster: UIImageView!
let movieCard: MovieCard
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
Bundle.main.loadNibNamed("MovieCardView", owner: self, options: nil)
guard let posterString = movieCard.poster_path else {
return
}
let urlString = "https://image.tmdb.org/t/p/w300" + posterString
guard let posterImageURL = URL(string: urlString) else {
return
}
poster.kf.setImage(with: posterImageURL)
}
}
我收到错误提示 属性 'self.movieCard' not initialized at super.init call for override init and required init methods。我该如何纠正这个问题?谢谢!
I am getting errors saying Property 'self.movieCard' not initialized at super.init call for both override init and required init methods.
Swift 编译器会阻止您创建未完全初始化的对象,因此在初始化超级 class 之前,您需要为 class 的对象提供值属性。
How do I rectify this?
您需要在调用 super.init
之前在初始化程序中为 movieCard
属性 提供一个值,或者使 movieCard
可选,以便编译器允许你把它留到以后再设置。例如,您可以将声明更改为:
var movieCard = MovieCard()
只给它一个空的 MovieCard
实例,然后将其设为 var
以便您以后可以更改它。您还可以标记变量 lazy
,这样除非您尝试访问 属性:
lazy var movieCard = MovieCard()
Copy/paste将以下代码添加到您的项目中。
public extension UIView {
class var bundle: Bundle { Bundle(for: self) }
class var identifier: String { String(describing: self) }
class var nibName: String { identifier }
class var nib: UINib { UINib(nibName: nibName, bundle: bundle) }
class func instantiateFromNib<T: UIView>() -> T {
return nib.instantiate(withOwner: nil, options: [:])[0] as! T
}
}
现在您可以在想要实例化您的自定义时执行此操作 UIView
。
let view: MovieCardView = MovieCardView.instantiateFromNib()
从 MovieCardView
开始,您可以删除所有 init
覆盖和 commonInit
方法。添加一种这样的方法。
func populateMovieCard(_ movieCard: MovieCard) {
// populate your details on to UI here
}
import UIKit
import Kingfisher
class MovieCardView: UIView {
@IBOutlet weak var poster: UIImageView!
var movieCard: MovieCard? = nil
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup(_ movieCard: MovieCard) {
self.movieCard = movieCard
guard let posterString = movieCard.poster_path else {
return
}
let urlString = "https://image.tmdb.org/t/p/w300" + posterString
guard let posterImageURL = URL(string: urlString) else {
return
}
poster.kf.setImage(with: posterImageURL)
}
}
// from controller when you initialising customview call this function from there like below
func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let movieCard = cards[index]
guard let customView = Bundle.main.loadNibNamed("MovieCardView", owner: nil, options: nil) as? MovieCardView else { return UIView() }
customView.setUp(movieCard);
return customView
}