Ios 在ScrollView中加载自定义UIView

Ios 在ScrollView中加载自定义UIView,ios,swift,uiview,uiscrollview,Ios,Swift,Uiview,Uiscrollview,我尝试添加在Interface Builder的HomeViewcontroller中链接的自定义视图。下面是故事板的一个屏幕截图: 所有插座都链接到转盘视图IBOutlets 这里是UIView文件(Interface Builder屏幕截图中的转盘视图): CarouselScrollView.swift import UIKit class CarouselView: UIView { @IBOutlet weak var assignmentStatusLabel: UILabel!

我尝试添加在Interface Builder的HomeViewcontroller中链接的自定义视图。下面是故事板的一个屏幕截图:

所有插座都链接到转盘视图
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个旋转视图填充滚动视图:

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
。一切似乎都很好。有人有解决方案或想法?。提前感谢您的时间和帮助。

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

如前所述,我必须在单独的Nib(.xib)文件中创建自定义视图。我希望有另一种解决方案,以便能够将customView保留在我的故事板中(使其刚好位于我的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中,我实例化了3个自定义视图,就像func 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.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
}
现在一切都正常了


感谢所有人,

检查标签是否正确连接到Interface Builder中的插座。谢谢,但已经做了几次,问题并不是这样。可能您在调用
awakeFromNib
之前使用了标签。而不是在情节提要中创建自定义视图,尝试在单独的Nib文件中创建它们。Paramasivan Samuttiram我按照您的建议做了,但我希望有另一种解决方案,以便能够将customView保留在我的故事板中(使它正好位于我的HomeController之上)。然后在CarouselView中我添加了这个:类func instanceFromNib()->UIView{return UINib(nibName:“CarouselView”,bundle:nil)。实例化(withOwner:nil,options:nil)[0]as!UIView},在HomeViewController中我实例化了3个自定义视图,就像我的循环中那样:let CarouselView=CarouselView.instanceFromNib()as!CarouselView谢谢,我怎么能不做两个循环而不是一个循环呢?而不是用户3057272如果您谈论的是“for”循环,那么您应该创建一个属性来跟踪它,可能是在“setupView”中