質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2510閲覧

[swift]カスタムUIViewのUILabelが更新できない

ouranosu

総合スコア6

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/04/21 11:12

よろしくお願いします。沼にハマってしまいました。

電卓アプリを作ってます。
storyboardではなく、コードで実装してます。
まだまだ電卓機能まで辿り着けず、単純に押したボタンの数字を表示するだけなのですが、つまづきました。

カスタムUIViewのUILabelを、別のカスタムUIViewで作ったボタンをおすと表示を変更するようにしたいのですが、変数の受け渡しはできていますが、UILabelに表示されません。
setNeedsDisplay()やlayoutIfNeeded()も試しましたが表示されません。
どうにも単純なところを見落としていると思うのですが、まる2日かけて細かく試してみましたが改善されません。
どうかお助けいただきますようお願いいたします。

ViewControllerが1つ。
カスタムUIViewが2つです。

ボタンを押すとMainViewControllerのcurrentTextに押したボタンのCurrentTitleが入ります。
didsetで関数を呼び出し、UILabelを持っているCurrentFormulaViewのラベルに値を入れてます。

MainViewController内のmakeCurrentFormulaView()でテキストに値を渡したあと、print(self.currentFormulaView.currentFormulaLabel.text!)でみてみると、間違いなく入っています。

再描写するには何が必要なのでしょうか?

MainViewController

1class MainViewController: UIViewController { 2 3 let currentFormulaView: CurrentFormulaView = CurrentFormulaView() 4 let buttonsView: ButtonsView = ButtonsView() 5 6 var currentText: String! { 7 didSet { 8 self.makeCurrentFormulaView() 9 } 10 } 11 12 var currentTextArray: [String]! 13 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 self.setupView() 18 } 19 20 private func setupView(){ 21 22 let stackView = UIStackView(arrangedSubviews: [self.currentFormulaView, self.buttonsView]) 23 stackView.axis = .vertical 24 stackView.spacing = 3 25 stackView.translatesAutoresizingMaskIntoConstraints = false 26 self.view.addSubview(stackView) 27 28 let languageViewConstant = CGFloat(50) 29 let formulaArrayViewConstant = CGFloat(100) 30 let currentFormulaViewConstant = CGFloat(200) 31 let buttonsViewConstant = CGFloat(self.view.bounds.height) - (formulaArrayViewConstant + currentFormulaViewConstant + 10) 32 33 [self.currentFormulaView.heightAnchor.constraint(equalToConstant: currentFormulaViewConstant), 34 self.buttonsView.heightAnchor.constraint(equalToConstant: buttonsViewConstant), 35 stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), 36 stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), 37 stackView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 10), 38 stackView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10)].forEach{ $0.isActive = true} 39 40 private func makeCurrentFormulaView() { 41 42 guard let text = currentText else { return } 43 self.currentFormulaView.currentFormulaLabel.text = text 44 //self.currentFormulaView.setLabelText(text: text) 45 } 46}

CurrentFormulaView

1class CurrentFormulaView: UIView { 2 3 var currentFormulaLabel: UILabel = { 4 let label = UILabel() 5 let viewWidth: CGFloat = CGFloat(UIScreen.main.bounds.width - 30) 6 let viewHeight: CGFloat = 250 7 8 label.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight) 9 label.tintColor = .black 10 label.textAlignment = .right 11 return label 12 }() 13 14 override init(frame: CGRect) { 15 super.init(frame: frame) 16 17 addSubview(currentFormulaLabel) 18 } 19 20 func setLabelText(text: String) { 21 //currentFormulaLabel.text = text 22 //print(currentFormulaLabel.text!) 23 } 24 25 override func layoutSubviews() { 26 super.layoutSubviews() 27 28 self.layer.cornerRadius = 25 29 self.layer.shadowColor = UIColor.black.cgColor 30 self.layer.shadowRadius = 10 31 self.layer.shadowOffset = CGSize(width: 7, height: 7) 32 self.layer.shadowOpacity = 0.5 33 self.layer.backgroundColor = UIColor.white.cgColor 34 } 35 36 required init?(coder: NSCoder) { 37 fatalError("init(coder:) has not been implemented") 38 } 39 40} 41

ButtonsView

1class ButtonsView: UIView { 2 3 let button1 = NumberButtonView(frame: .zero, titleName: "1") 4 let button2 = NumberButtonView(frame: .zero, titleName: "2") 5 let button3 = NumberButtonView(frame: .zero, titleName: "3") 6 let button4 = NumberButtonView(frame: .zero, titleName: "4") 7 let button5 = NumberButtonView(frame: .zero, titleName: "5") 8 let button6 = NumberButtonView(frame: .zero, titleName: "6") 9 let button7 = NumberButtonView(frame: .zero, titleName: "7") 10 let button8 = NumberButtonView(frame: .zero, titleName: "8") 11 let button9 = NumberButtonView(frame: .zero, titleName: "9") 12 let button0 = NumberButtonView(frame: .zero, titleName: "0") 13 let button00 = NumberButtonView(frame: .zero, titleName: "00") 14 let buttonPeriod = NumberButtonView(frame: .zero, titleName: ".") 15 let buttonPlus = NumberButtonView(frame: .zero, titleName: "+") 16 let buttonMinus = NumberButtonView(frame: .zero, titleName: "-") 17 let buttonProduct = NumberButtonView(frame: .zero, titleName: "x") 18 let buttonDivide = NumberButtonView(frame: .zero, titleName: "÷") 19 let buttonEqual = NumberButtonView(frame: .zero, titleName: "=") 20 let buttonAllClear = NumberButtonView(frame: .zero, titleName: "AC") 21 let buttonBackClear = NumberButtonView(frame: .zero, titleName: "←") 22 let buttonPercent = NumberButtonView(frame: .zero, titleName: "%") 23 24 override init(frame: CGRect) { 25 super.init(frame: frame) 26 27 let stack1 = createStackView(button1: buttonAllClear, button2: buttonBackClear, button3: buttonPercent, button4: buttonDivide) 28 let stack2 = createStackView(button1: button7, button2: button8, button3: button9, button4: buttonProduct) 29 let stack3 = createStackView(button1: button4, button2: button5, button3: button6, button4: buttonMinus) 30 let stack4 = createStackView(button1: button1, button2: button2, button3: button3, button4: buttonPlus) 31 let stack5 = createStackView(button1: button0, button2: button00, button3: buttonPeriod, button4: buttonEqual) 32 33 let baseStackView = UIStackView(arrangedSubviews: [stack1, stack2, stack3, stack4, stack5]) 34 baseStackView.axis = .vertical 35 baseStackView.distribution = .fillEqually 36 baseStackView.spacing = 0 37 baseStackView.translatesAutoresizingMaskIntoConstraints = false 38 39 addSubview(baseStackView) 40 41 baseStackView.anchor(top: topAnchor, bottom: bottomAnchor, left: leftAnchor, right: rightAnchor) 42 } 43 44 private func createStackView(button1: NumberButtonView, button2: NumberButtonView, button3: NumberButtonView, button4: NumberButtonView) -> UIStackView { 45 46 let returnView = UIStackView(arrangedSubviews: [button1, button2, button3, button4]) 47 returnView.axis = .horizontal 48 returnView.distribution = .fillEqually 49 returnView.spacing = 0 50 returnView.translatesAutoresizingMaskIntoConstraints = false 51 52 return returnView 53 54 } 55 56 required init?(coder: NSCoder) { 57 fatalError("init(coder:) has not been implemented") 58 } 59 60} 61 62class NumberButtonView: UIView { 63 64 var button: NumberButton? 65 66 init(frame: CGRect, titleName: String) { 67 super.init(frame: frame) 68 69 let buttonWidth = UIScreen.main.bounds.width / 5 70 71 button = NumberButton(type: .custom) 72 button?.setTitle(titleName, for: .normal) 73 button?.backgroundColor = .cyan 74 button?.setTitleColor(.darkGray, for: .normal) 75 button?.titleLabel!.font = UIFont.systemFont(ofSize: 30) 76 button?.titleLabel!.adjustsFontSizeToFitWidth = true 77 button?.layer.cornerRadius = buttonWidth / 2 78 79 button?.layer.shadowColor = UIColor.black.cgColor 80 button?.layer.shadowRadius = 5 81 button?.layer.shadowOffset = CGSize(width: 3, height: 3) 82 button?.layer.shadowOpacity = 0.5 83 //button?.layer.backgroundColor = UIColor.white.cgColor 84 85 button?.addTarget(self, action: #selector(tappedButton(_ :)), for: .touchDown) 86 87 addSubview(button!) 88 89 button?.anchor(centerY: centerYAnchor, centerX: centerXAnchor, width: buttonWidth, height: buttonWidth) 90 } 91 92 @objc private func tappedButton(_ sender: UIButton) { 93 94 guard let title = sender.currentTitle else { return } 95 MainViewController().currentText = String(title) 96 } 97 98 required init?(coder: NSCoder) { 99 fatalError("init(coder:) has not been implemented") 100 } 101} 102 103//押した時のアクション 104class NumberButton: UIButton { 105 106 override var isHighlighted: Bool { 107 didSet { 108 if isHighlighted { 109 UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: []) { 110 111 self.transform = .init(scaleX: 0.8, y: 0.8) 112 self.layoutIfNeeded() 113 } 114 } else { 115 UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: []) { 116 117 self.transform = .identity 118 self.layoutIfNeeded() 119 } 120 } 121 } 122 } 123 124 override init(frame: CGRect) { 125 super.init(frame: frame) 126 } 127 128 required init?(coder: NSCoder) { 129 fatalError("init(coder:) has not been implemented") 130 } 131} 132

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/04/21 13:37

なんか制約エラーがたくさん出ますけど…。どんな画面を作りたいのでしょうか?
ouranosu

2021/04/21 14:56

hoshi-takanori様 見ていただきありがとうございます。 おそらくあと2つ、小さなカスタムUIViewがあるために、このコードでは制約エラーが発生したのかもしれません。 今回の質問とは無関係な部分だったために省きました。StackViewも省くべきでしたね。 問題は解決いたしました。ありがとうございました!
guest

回答1

0

ベストアンサー

swift

1MainViewController().currentText = String(title)

これは、今画面に表示しているMainViewControllerとは別の新しいMainViewControllerインスタンスを生成し、そのcurrentTextプロパティを更新していますから、今画面に表示しているCurrentFormulaView のUILabelは何も更新されていません。

今画面に表示しているMainViewControllerを取得し、そのcurrentTextプロパティを更新する必要があります。

投稿2021/04/21 14:06

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ouranosu

2021/04/21 14:54

TakeOne様 ご指摘ありがとうございます!インスタンスを作成するのではなく、親VC情報を取得してみたところ、うまく動作しました! 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問