32771


簡単なTodoリストを作ろうとしています。現時点は、チェックボックスを作り終えた段階です。  
evernoteのように、改行したら新しいチェックボックスが出現するようにしたのですが、苦戦しています。textFieldShouldReturnを使おうとしているのですが、ここで生成しているつもりのボタンが画面に表示されません。（resignFristResponder()の改行は反映されています。）どこが悪いのか、ご指摘頂けたら幸いです。  
※以下では、子クラスとしてチェックボックスを生成する「CheckBox」というクラスを持っています。

[code]

    import UIKit
    
    class ViewController: UIViewController,UITextFieldDelegate {
    
        @IBAction func button(_ sender: CheckBox) {
        }
        @IBOutlet weak var WhatToDo: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            WhatToDo.delegate = self
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
        func textFieldShouldReturn(_ WhatToDo: UITextField) -> Bool {
            let newBox : UIButton = CheckBox()
            newBox.layer.position = CGPoint(x: 100, y:100)
            newBox.backgroundColor = UIColor.red
            self.view.addSubview(newBox)
            WhatToDo.resignFirstResponder()
            return true
        }
    }
    
    class CheckBox: UIButton {
        let checkedImage = UIImage(named: "checked-box")
        let uncheckedImage = UIImage(named: "unchecked-box")
    
        var isChecked : Bool = false{
            didSet{
                if isChecked == true{
                    self.setImage(checkedImage, for:.normal)
                }else{
                    self.setImage(uncheckedImage, 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]


CC BY-SA 3.0
2017-02-17T15:21:23.600
32755
2017-02-18T15:35:14.547
2017-02-18T10:27:15.757
20671
20671
question
swift xcode
textFieldShouldReturnで生成したつもりのボタンが表示されない

[code]

    newBox.layer.position = CGPoint(x: 100, y:100)
    
[/code]

この行を次に書き換えてください。

[code]

    newBox.frame = CGRect(x: 100.0, y: 100.0, width: 80.0, height: 60.0)
    
[/code]

チェックボックスが表示されると思います。  
`UIButton`のサブクラス`CheckBox`のイニシアライザがどうなってるかなんですけど、そこで、表示のサイズ（`CGSize`）の設定が含まれていないと、`UIButton`（のスーパークラスの`UIView`）のデフォルト`CGRect.zero`、すなわち面積0になるので、表示されても見えない状態となります。


CC BY-SA 3.0
2017-02-18T00:28:53.587
32759
2017-02-18T00:28:53.587
18540
32755
answer


根本的には、 **`CheckBox`の実装が`init()`でインスタンス化できるように作られていない**
というのが原因ですね。`awakeFromNib()`というのはNibファイル(xibかstoryboard)からインスタンス化した時にしか呼ばれないので、`init()`でインスタンス化した場合には、正しく初期化されません。

例えば、`CheckBox`クラスに次のようなコードを書き加えてみてください。

[code]

    init() {
        let frm = CGRect(origin: CGPoint.zero, size: checkedImage.size)
        super.init(frame: frm)
        awakeFromNib()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
[/code]

上記の修正だけでもチェックボックスが表示されるようになるはずですが、コメントに書いたように`layer.position`で位置合わせをするのは標準的とは言えないので、`addSubview`する部分は例えば次のように書き換えるべきでしょう。

[code]

        let newBox : UIButton = CheckBox()
        newBox.frame = CGRect(origin: CGPoint(x: 100, y:100), size: newBox.frame.size) //<- 表示位置は`frame`で指定する
        newBox.backgroundColor = UIColor.red
        self.view.addSubview(newBox)
    
[/code]

* * *

上記に非掲載の部分でコードの読みにくい部分を書き換えながら試したので、若干修正が必要かもしれません。何かお気付きの点があればコメント等でお知らせください。

コメントで指摘していただきましたが、上記のコードは、プロパティの宣言を

[code]

    let checkedImage = UIImage(named: "checked-box")!
    let uncheckedImage = UIImage(named: "unchecked-box")!
    
[/code]

のように修正したのを前提で書いてありましたが、その点を記載し忘れていました。ご指摘ありがとうございます。(`UIImage.init(named:)`が`nil`を返すのは、アプリの構成ミスで`"checked-
box"`とかで指定された画像リソースが存在しない場合だけなので、意図的にさっさと強制アンラップの`!`を使用しています。)


CC BY-SA 3.0
2017-02-18T11:07:40.960
32771
2017-02-18T15:35:14.547
2017-02-18T15:35:14.547
13972
13972
32755
answer