如何将额外参数传递给链接到 XIB 文件的自定义 UIView?
Posted
技术标签:
【中文标题】如何将额外参数传递给链接到 XIB 文件的自定义 UIView?【英文标题】:How to pass in extra arguments to a custom UIView that is linked to a XIB file? 【发布时间】:2021-09-21 07:15:01 【问题描述】:我目前有一个名为 MovieCard 的数据类型,它包含有关电影的所有数据,它需要显示在卡片上,也就是 UIView。我创建了一个名为 MovieCardView 的自定义 UIView 类,并通过 File's Owner 将其链接到 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 并以编程方式将 IBOutlets 设置为我的 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)
我收到错误消息,提示在 super.init 调用时未对重写 init 和所需的 init 方法初始化 Property 'self.movieCard'。我该如何纠正这个问题?谢谢!
【问题讨论】:
为此您需要在MovieCardView
中声明一个变量并将其设置为commoninit()
嗨@jatinfl 你的意思是像 let movieCard: MovieCard 作为 IBOutlets 之后的一行,然后在 commonInit() 中设置 moviePoster = movieCard.poster 吗?我也可以检查捆绑加载代码是否正常?谢谢!
是的,试试这个,如果你卡在这里 ping 我。
嗨@jatinfl 我已经尝试过你所说的并且遇到了另一个错误,我已经在上面的帖子中添加了更新,我可以知道如何纠正这个错误吗?谢谢!
你需要设置图片。对吗?
【参考方案1】:
我收到错误消息,提示在 super.init 调用重写 init 和必需的 init 方法时未初始化 Property 'self.movieCard'。
Swift 编译器会阻止您创建未完全初始化的对象,因此在初始化超类之前,您需要为类的属性提供值。
我该如何解决这个问题?
在调用super.init
之前,您需要在初始化程序中为movieCard
属性提供一个值,或者将movieCard
设为可选,以便编译器允许您稍后再设置它。例如,您可以将声明更改为:
var movieCard = MovieCard()
只给它一个空的MovieCard
实例,并使其成为var
,以便您以后可以更改它。您还可以标记变量 lazy
以便实际上不会创建空的 MovieCard,除非您尝试访问该属性的值:
lazy var movieCard = MovieCard()
【讨论】:
【参考方案2】:将以下代码复制/粘贴到您的项目中。
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
【讨论】:
感谢您的回复。我在实现您的代码时遇到错误:由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[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
【讨论】:
感谢您的回复。我在实现您的代码时遇到错误:由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[以上是关于如何将额外参数传递给链接到 XIB 文件的自定义 UIView?的主要内容,如果未能解决你的问题,请参考以下文章
如何将额外的参数传递给 django admin 自定义表单?