34472


最初の行にUITextFieldとチェックボックスを表示して、UITextFieldでreturnキーを押した時に、次の行に新しいUITextFieldとチェックボックスが表示されるようなプログラムを作りたいのですが、UITextFieldはいまくいったもののチェックボックスが作動しません。どうすれば作動するのでしょうか。  
以下、親クラス、子クラスの順番となっています。

[code]

    import UIKit
    
    class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet weak var firstBox: UIButton!
    
    var newBox: UIButton!
    
    @IBOutlet weak var firstTextField: UITextField!
    
    var counter = 0
    
    var newTextField: UITextField!
    
    var currentTextField: UITextField!
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
    {
        textField.resignFirstResponder()
        counter += 1
        createNewTextFieldAndBox(parameter: counter)
        return true
    }
    
    func createNewTextFieldAndBox(parameter: Int)
    {
        //information of the textfields
        let tWidth = Int(firstTextField.frame.width)        //250
        let tHeight = Int(firstTextField.frame.height)      //30
        let XofTextField = Int(firstTextField.frame.origin.x)
        let YofTextField = (Int(firstTextField.frame.origin.y) + 16)*parameter + 20
    
        //information of the boxes
        let bWidth = Int(firstBox.frame.width)
        let bHeight = Int(firstBox.frame.height)
        let XofBox = Int(firstBox.frame.origin.x)
        let YofBox = (Int(firstBox.frame.origin.y) + 16)*parameter + 20
    
        //create new TF
        newTextField = UITextField(frame: CGRect(x: XofTextField, y: YofTextField, width: tWidth, height: tHeight))
        self.view.addSubview(newTextField)
        currentTextField = newTextField
        currentTextField.delegate = self
    
        //create new Box
        newBox = UIButton(frame: CGRect(x: XofBox, y: YofBox, width: bWidth, height: bHeight))
    
        newBox.setImage(#imageLiteral(resourceName: "uncheckedBox"), for: .normal)
        self.view.addSubview(newBox)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        firstTextField.delegate = self
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    }
    
[/code]

以下、子クラスです。

[code]

    import UIKit
    
    class CheckBox: UIButton {
    var isChecked:Bool = false
    {
        didSet
        {
            if isChecked == true
            {
                self.setImage(#imageLiteral(resourceName: "checkedBox"), for: .normal)
            }
            else
            {
                self.setImage(#imageLiteral(resourceName: "uncheckedBox"), for: .normal)
            }
        }
    }
    
    override func awakeFromNib()
    {
        self.addTarget(self, action: #selector(self.buttondClicked(_:)), for: UIControlEvents.touchUpInside)
        self.isChecked = false
    }
    
    func buttondClicked(_ sender:UIButton)
    {
        if(sender == self)
        {
            if isChecked == true
            {
                isChecked = false
            }
            else
            {
                isChecked = true
            }
        }
    }
    }
    
[/code]

一部インデントがおかしくなっているところがあるかもしれませんがご容赦ください。また、子クラスのawakeFromNib以下やその周辺のコードはネットから引っ張ってきたものをほぼコピペしただけのものなので、あまりコードの意味がわかっていない状況です。ここのあたりのコードも新しいチェックボックスが作動しないことと関係あるのでしょうか。


CC BY-SA 3.0
2017-05-05T12:40:01.110
34469
2017-05-05T13:21:23.257
2017-05-05T13:07:09.717
20671
20671
question
swift xcode swift3 xcode8
returnで生成されたはずのチェックボックスが作動しない。


表示されているチェックボックスが動作しない理由は2点あります。

  * チェックボックスとしての動作は`CheckBox`に実装されているのに、ただの`UIButton`をインスタンス化している
  * `CheckBox`クラスでは`awakeFromNib()`により、チェックされた時のactionを指定しているが、普通のコンストラクタでインスタンス化すると`awakeFromNib()`が呼ばれない

と言うわけで、修正点としては、

チェックボックスとして使いたいボタンは`CheckBox`と宣言しましょう:

[code]

    @IBOutlet weak var firstBox: CheckBox!
    
    var newBox: CheckBox!
    
[/code]

Nib(.xibや.storyboard)からインスタンス化しないのであれば、明示的に`awakeFromNib()`を呼んでやりましょう:

[code]

        //create new Box
        newBox = CheckBox(frame: CGRect(x: XofBox, y: YofBox, width: bWidth, height: bHeight))
        newBox.awakeFromNib() //<-
    
        newBox.setImage(#imageLiteral(resourceName: "uncheckedBox"), for: .normal)
        self.view.addSubview(newBox)
    
[/code]

と言うことになります。

普通は部品として公開するようなコードについては、上記2点目のような注意はしなくて良いようにするものなのですが、あなたが参照されたコードは実用的と言うよりかなり実験的なものですね。本当は書き換えたい部分がいっぱいあるのですが、本質的では無いのでここでは遠慮しておきます。

上記2点の修正を行ってみて、まだ何か思うように動作しない点があれば、コメント等でお知らせください。


CC BY-SA 3.0
2017-05-05T13:21:23.257
34472
2017-05-05T13:21:23.257
13972
34469
answer