如何制作可重用的UIView模板以及UILabels

时间:2014-10-23 05:32:23

标签: ios objective-c iphone uiview swift

我正在构建一个天气应用程序作为初学者项目。假设我想要一个自定义视图,其中包含许多UILabel的温度,湿度,降水等。这个想法是,这个自定义UIView将被用于用户保存的每个城市多次。如果用户保存了3个城市,则自定义视图将包含3个实例。

最好的方法是什么?我正在尝试将UIView子类化。最初我覆盖了drawRect(rect:CGRect)并在那里定义了我的UILabels。那感觉不对劲。在我尝试更新NSURLSession上的完成处理程序中的标签文本之后,它将不会得到alloc / inited。

或者我应该覆盖init(),这使我这样做:

required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

我不知道这意味着什么。然后,当我尝试在根VC上使用框架初始化时,我不得不做这样的事情。

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

有人能指引我完成最好的方法吗?我有类似下面的内容但是当我尝试将UILabels添加到自定义类的子视图时,我得到了一个零值。

class ViewTemplate: UIView {

var tempLabel: UILabel!
var humidityLabel: UILabel!

override init () {

tempLabel = UILabel()
tempLabel.frame = CGRectMake(halfScreenWidth - 130, 120, 260, 130)
tempLabel.textColor = UIColor.whiteColor()
tempLabel.backgroundColor = UIColor.clearColor()

// similar stuff for humidityLabel

super.init()        
addSubview(tempLabel)

}

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

required init(coder aDecoder: NSCoder) {
 fatalError("init(coder:) has not been implemented")
}
}

如果不太确定nil来自哪里。但最重要的是,我正在寻找这样做的最佳实践。 谢谢!

3 个答案:

答案 0 :(得分:1)

用于创建个人视图:

  1. 创建新的View文件。 UIView的子类。确保在执行此操作时也创建xib文件。
  2. 在故事板(标签等)中绘制项目并将它们连接到swift文件
  3. 通过将xib文件设置为刚创建的swift文件的自定义类,确保将它们连接到storyboard中。
  4. 在awakeFromNib()方法中实例化它们。 如果文本是标签,请务必设置文本的默认值。否则,它们会在实例化时显示为nil,并且您的应用程序将崩溃。

    导入UIKit

    类MyView:UIView {

    @IBOutlet weak var templabel:UILabel!

    覆盖func awakeFromNib(){     super.awakeFromNib()     self.tempLabel.text =“95度”

    }

  5. 加载到viewcontroller:

    1a上。创建一个实现UIScrollView的viewcontroller。 1B。在故事板中放置UIScrollview并将其连接到该视图控制器

    class MyWeatherViewController: UIViewController, UIScrollViewDelegate {
    
    @IBOutlet var scrollView: UIScrollView! 
    

    2a上。在ViewDidLoad中,创建您要创建的UIView的实例。单独填充它们。 2B。在ViewDidLoad中,将scrollview宽度设置为单个View的宽度。将高度设置为单个View的高度*您希望显示的视图数

           var view1: MyView = MyView()
           var view2: MyView = MyView()
           let viewArray[MyView!] = [view1, view2]
    
          for items in viewArray {
           var frame = scrollView.bounds
    
            //Set the origin of the views
            frame.origin.x = 0.0
            frame.origin.y = frame.size.height * items
    
            //create a view out of the object provided, define it's frame, and add to scrollview
            let viewToAdd = viewArray[items].view
            newPageView.frame = frame
            scrollView.addSubview(viewToAdd)
    

    //设置要显示的标签。您必须在将负载加载到滚动视图后执行此操作            viewArray [items] .tempLabel.text =“105度”        }

    请记住,您需要设置另一个数据模型来保存要显示的信息。我建议创建一个包含您想要显示的信息的数组,这样您就可以使用您想要设置的所有标签来执行viewArray [items] .tempLabel.text = tempArray [items]。

    这应该垂直对齐它们以滚动和查看所有项目的能力。

    这也可以根据用户保存的城市动态决定要添加的视图数量。只需修改逻辑即可阅读用户拥有的许多城市等。

答案 1 :(得分:0)

你走在正确的轨道上。

  1. 声明标签的属性。看起来你已经做到了。就个人而言,我会将其声明为let而不是var的常量,因为您应该始终拥有这些标签。
  2. 覆盖init(frame: CGRect)方法。再次,看起来你已经开始这样了。您应该覆盖init(frame: CGRect)的原因是init(),因为init()只是调用init(frame: CGRectZero)。如果你只实现init(),那么你的一些属性可能不会被初始化(尽管这对Swift来说不是一个问题,因为你可以将属性声明为常量,因此编译器会抛出错误)。在您的初始化程序中,您需要初始化所有标签&在致电super.init(frame)之前设置它们。调用super.init(frame)方法后,您应该将标签添加为self的子视图。
  3. 如果您以编程方式放置UI,请覆盖layoutSubviews()。您可以使用此方法执行所有大小调整和布局子视图。我这样做的一切都是我最熟悉的。如果你正在使用AutoLayout,我认为最好的做法是在课程的初始化程序中应用这些约束,因为它们只需要设置一次。
  4. 或者,您可能还想覆盖sizeThatFits()。这将确保在调用sizeToFit()时,您的视图始终是正确的大小。
  5. 这不仅适用于UIView,而且适用于它的任何子类。

答案 2 :(得分:0)

您可以使用UIViewController扩展并初始化采用UIView的UIView函数。您可以在项目中的任何地方使用它。

extension UIViewController {
  func setView(_ view: UIView){
     view.backgroundColor = UIColor()
     view.layer.cornerRadius = 5.0
     // customize your view
  }
}

然后:声明您在Controller中查看并在viewDidLoad()上调用该函数时传递它

let myView = UIView()
setView(myView)