在 ScrollView 中加载自定义 UIView

Posted

技术标签:

【中文标题】在 ScrollView 中加载自定义 UIView【英文标题】:Load Custom UIView in ScrollView 【发布时间】:2017-04-21 19:12:49 【问题描述】:

我尝试在 Interface Builder 的 HomeViewcontroller 中添加我的 customView。这是故事板的截图:

所有网点都链接到 CarouselView IBOutlets

这里是 UIView 文件(Interface Builder 的屏幕截图中的轮播视图):

CarouselScrollView.swift

import UIKit

class CarouselView: UIView 
@IBOutlet weak var assignmentStatusLabel: UILabel!
@IBOutlet weak var assignmentCustomerLabel: UILabel!
@IBOutlet weak var assignmentAgencyLabel: UILabel!
@IBOutlet weak var assignmentPeriodLabel: UILabel!
@IBOutlet weak var nextAssignmentButton: UIButton!
@IBOutlet weak var previousAssignmentButton: UIButton!

init(frame: CGRect, _ status: String, _ customer: String, _ agency: String, _ period: String) 
    super.init(frame: frame)
    self.setupView("status", "customer", "agency", "period")


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


func setupView(_ status: String, _ customer: String, _ agency: String, _ period: String) 
    //        self.assignmentStatusLabel.text = status
    //        self.assignmentCustomerLabel.text = customer
    //        self.assignmentAgencyLabel.text = agency
    //        self.assignmentPeriodLabel.text = period

这里是我的 ViewController,我用 3 个 CarouselView 填充我的滚动视图:

import UIKit
class HomeViewController: BaseViewController, HomeView 

@IBOutlet weak var carouselScrollView: UIScrollView!
@IBOutlet weak var carouselView: CarouselView!

var presenter: HomePresenter?
var currentAssignmentView: Int = 0
// create array of assignments for test
let arrayOfAssignments = [["status":"Mission en cours", "customer":"customer1", "agency":"bourg", "startDate":"09-05-2016", "endDate":"10-05-2016"],
                          ["status":"Mission à venir", "customer":"customer2", "agency":"agency paris", "startDate":"09-01-2017", "endDate":"03-04-2017"],
                          ["status":"Mission passée", "customer":"customer3", "agency":"agency lyon", "startDate":"09-09-2017", "endDate":"29-05-2018"]
]

override func initPresenter() -> BasePresenter 
    let presenter = HomePresenter(self, Navigator(self))
    self.presenter = presenter
    return presenter


override func setup() 
    self.navBarTitleImageSetup()


override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()
        self.scrollViewSetup()


func scrollViewSetup() 
    let carouselScrollViewWidth:CGFloat = self.carouselScrollView.frame.width
    let carouselScrollViewHeight:CGFloat = self.carouselScrollView.frame.height
    let numberOfAssignments = self.arrayOfAssignments.count

    self.carouselScrollView.contentSize = CGSize(width: carouselScrollViewWidth * CGFloat(numberOfAssignments), height: carouselScrollViewHeight)
    for i in 0...numberOfAssignments - 1 
        let carouselView = CarouselView(frame: CGRect(x: carouselScrollViewWidth * CGFloat(i), y: CGFloat(0), width: carouselScrollViewWidth, height: carouselScrollViewHeight), "iuhiuh", "oiojoij", "iuhiuh", "iuhiuhiuh")
        switch i 
        case 0:
            carouselView.backgroundColor = UIColor.blue
        case 1:
            carouselView.backgroundColor = UIColor.yellow
        case 2:
            carouselView.backgroundColor = UIColor.gray
        default:
            break
        
        self.carouselScrollView.addSubview(carouselView)
    
    self.carouselScrollView.delegate = self


func navBarTitleImageSetup() 
    let image: UIImage = #imageLiteral(resourceName: "NavLogo")
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 97, height: 24))
    imageView.contentMode = .scaleAspectFit
    imageView.image = image
    self.navigationItem.titleView = imageView


extension HomeViewController: UIScrollViewDelegate 
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 
    let viewWidth: CGFloat = self.carouselScrollView.frame.width
    let currentAssignmentNumber: CGFloat = floor((self.carouselScrollView.contentOffset.x - viewWidth/2)/viewWidth)+1
    self.currentAssignmentView = Int(currentAssignmentNumber)

当我像这样构建和运行时,我可以滚动滚动视图(添加了 3 个视图)但没有标签(正常,因为已评论):

但是当我在 CarouselScrollView.swift 文件中取消注释其中一行时:

    //        self.assignmentStatusLabel.text = status
    //        self.assignmentCustomerLabel.text = customer
    //        self.assignmentAgencyLabel.text = agency
    //        self.assignmentPeriodLabel.text = period

我在控制台中有这个错误:

致命错误:在展开可选值时意外发现 nil

我不明白为什么我的标签是nil。一切似乎都很好。有人有解决方案或想法吗?提前感谢您的时间和帮助。

【问题讨论】:

检查标签是否正确连接到 Interface Builder 中的插座。 谢谢你,但已经做了几次,问题不在于。 也许您在调用awakeFromNib 之前使用了标签。 不要在 Storyboard 中创建自定义视图,而是尝试在单独的 Nib 文件中创建它们。 Paramasivan Samuttiram 我按照你的建议做了,但我希望有另一种解决方案,以便能够将 customView 保留在我的 Storyboard 中(将其保留在我的 HomeController 上方)。然后在 CarouselView 我添加了这个:class func instanceFromNib() -> UIView return UINib(nibName: "CarouselView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView 和 HomeViewController 我在循环中实例化了我的 3 个自定义视图:让 carouselView = CarouselView.instanceFromNib() 为! CarouselView 谢谢, 【参考方案1】:

如果您在将carouselView 添加为子视图后调用setupView,则该问题将得到解决,因为只有在添加为子视图后,您的标签才会被初始化。

【讨论】:

如何在不制作 2 个循环而不是 1 个循环的情况下做到这一点?比你用户3057272 如果你在谈论'for'循环,那么你应该在'setupView'中创建一个跟踪它的属性【参考方案2】:

就像 Paramasivan Samuttiram 所说,我必须在单独的 Nib(.xib) 文件中创建我的 customView。我希望有另一种解决方案,以便能够将 customView 保留在我的 Storyboard 中(将其保留在我的 HomeController 上方),但这确实成功了。

在 CarouselView 我添加了这个:

class func instanceFromNib() -> UIView  return UINib(nibName: "CarouselView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView 

现在 CarouselView 文件如下所示:

class CarouselView: UIView 
@IBOutlet weak var assignmentStatusLabel: UILabel!
@IBOutlet weak var assignmentCustomerLabel: UILabel!
@IBOutlet weak var assignmentAgencyLabel: UILabel!
@IBOutlet weak var assignmentPeriodLabel: UILabel!
@IBOutlet weak var nextAssignmentButton: UIButton!
@IBOutlet weak var previousAssignmentButton: UIButton!

class func instanceFromNib() -> UIView 
    return UINib(nibName: "CarouselView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView


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


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

在 HomeViewController 中,我在 func scrollViewSetup 的循环中实例化了我的 3 个自定义视图:

func scrollViewSetup() 
    let carouselScrollViewWidth:CGFloat = self.carouselScrollView.frame.width
    let carouselScrollViewHeight:CGFloat = self.carouselScrollView.frame.height
    let numberOfAssignments = self.arrayOfAssignments.count

    self.carouselScrollView.contentSize = CGSize(width: carouselScrollViewWidth * CGFloat(numberOfAssignments), height: carouselScrollViewHeight)
    for i in 0...numberOfAssignments - 1 
        let carouselView = CarouselView.instanceFromNib() as! CarouselView
        carouselView.frame = CGRect(x: carouselScrollViewWidth * CGFloat(i), y: CGFloat(0), width: carouselScrollViewWidth, height: carouselScrollViewHeight)
        carouselView.assignmentStatusLabel.text = self.arrayOfAssignments[i]["status"]
        carouselView.assignmentCustomerLabel.text = self.arrayOfAssignments[i]["customer"]?.uppercased()
        carouselView.assignmentAgencyLabel.text = self.arrayOfAssignments[i]["agency"]?.uppercased()
        carouselView.assignmentPeriodLabel.text = "\(self.arrayOfAssignments[i]["startDate"]!)  -  \(self.arrayOfAssignments[i]["endDate"]!)"
        self.carouselScrollView.addSubview(carouselView)
    
    self.carouselScrollView.delegate = self

现在一切正常。

谢谢大家,

【讨论】:

以上是关于在 ScrollView 中加载自定义 UIView的主要内容,如果未能解决你的问题,请参考以下文章

你如何在 django 中加载自定义字段

在临时分发中加载自定义框架时出错

xml Miva - 在URI模板中加载自定义字段

如何在 Django 管理主页中加载自定义 JS 文件?

Android:在 SD 卡中加载自定义字体

在 Elasticsearch 中加载自定义同义词文件时出错