UIView子类可以创建其他自定义视图实例吗?

时间:2015-07-09 20:24:59

标签: ios swift uiview

我有一个名为LifeCounter的UIView子类,我想为每个玩家创建一个。我能够向Main.storyboard添加两个视图,通过Attributes面板将它们的类设置为LifeCounter,并以这种方式创建多个实例,连接到视图控制器,更改属性等。

我现在想的是创建一个更大的视图GameHeader,它将保存LifeCounters和一些其他补充信息,如时间,游戏重置按钮等.GameHeader是UIView的子类,但我不能让它在模拟器中绘制我的LifeCounter视图,我不知道为什么。

GameHeader目前是一个拖入故事板的视图,并给它带有属性面板的类。

GameHeader.swift

import UIKit

class GameHeader: UIView {

// MARK: Properties

// The Frame
let topFrame = CGRect(x: 0, y: 0, width: 320, height: 200)

// MARK: Initlization
required init() {
    super.init(frame: topFrame)

    // Adds the player one counter
    let playerOneCounter = LifeCounter()
    addSubview(playerOneCounter)

}

required init(coder aDecoder: NSCoder) {
    // Calls the super class (UIView) initializer
    super.init(coder: aDecoder)
}

}

LifeCounter.swift

import UIKit

class LifeCounter: UIView {

// MARK: Propterties

// Starting life total
var lifeTotal = 20 {
    didSet {
        // Updates the layout whenever the lifeTotal is updated
        setNeedsLayout()
    }
}

// Creates the UI Labels
// All created views need a defined frame for where they sit
// Is this neccesary outside of the init? Is there a better way?
var counter = UILabel(frame: CGRect(x: 0, y: 20, width: 100, height: 90))
var playerName = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
var winner = ""



// MARK: Initlization

// First init. LifeCounter takes a frame parameter, the adds the labels etc.
init() {
    super.init(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
    self.addLifeCounter()
}

required init(coder aDecoder: NSCoder) {
    // Calls the super class (UIView) initializer
    super.init(coder: aDecoder)
}

func addLifeCounter() {
    print("addLifeCounter is running")
    // Styles life counter label
    counter.textColor = UIColor.blackColor()
    counter.textAlignment = .Center
    counter.font = UIFont.boldSystemFontOfSize(72)
    counter.text = String(lifeTotal)

    // Styles playerName label
    playerName.text = "Player Name"
    playerName.textAlignment = .Center


    // Button
    let minusButton = UIButton(frame: CGRect(x: 5, y: 110, width: 40, height: 40))
    let plusButton = UIButton(frame: CGRect(x: 55, y: 110, width: 40, height: 40))

    minusButton.backgroundColor = UIColor.redColor()
    plusButton.backgroundColor = UIColor.blueColor()

    // Button action
    minusButton.addTarget(self, action: "minusLife:", forControlEvents: .TouchDown)
    plusButton.addTarget(self, action: "plusLife:", forControlEvents: .TouchDown)

    addSubview(playerName)
    addSubview(counter)
    addSubview(minusButton)
    addSubview(plusButton)
}


// MARK: Button actions
func minusLife(minusButton: UIButton) {
    lifeTotal -= 1
    counter.text = String(lifeTotal)
}

func plusLife(plusButton: UIButton) {
    lifeTotal += 1
    counter.text = String(lifeTotal)
}

}

2 个答案:

答案 0 :(得分:1)

init(coder:)是从故事板或笔尖创建视图时调用的初始化程序。如果您移动创建并在其中添加LifeCounter个实例的代码,它应该可以正常工作。

使其更可重用的一个好策略是创建一个从两个初始化程序调用的设置方法,以便它可以运行,无论它来自故事板/笔尖还是以编程方式实例化。

class GameHeader: UIView {
    let topFrame = CGRect(x: 0, y: 0, width: 320, height: 200)

    required init() {
        super.init(frame: topFrame)
        self.setupSubviews()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setupSubviews()
    }

    func setupSubviews() {
        let playerOneCounter = LifeCounter()
        addSubview(playerOneCounter)
    }

}

答案 1 :(得分:0)

我发现错误在于将LifeController绘图代码放在init(frame :)块而不是Coder块中。通过Interface Builder添加视图时,它使用init(编码器:)而不是init(frame:)