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

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

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

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

Swift

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

Q&A

解決済

1回答

2759閲覧

画面を上下にスクロールすると文字化けが起こるバグを直したい

reveco

総合スコア13

Xcode

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

Swift

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

0グッド

1クリップ

投稿2016/11/28 06:59

###前提・実現したいこと
現在swift3.0を学んで約1か月のプログラミング初心者です。
画面を上下にスクロールした時に文字化けするバグが発生しており、画面を上下にスクロールしても文字化けしないように修正したいです。

質問も初めてですので何を言っているのか分かりづらいかもしれませんが、アドバイスをお願い致します。

ことらはバグが発生した時のスクショになります。

イメージ説明

###原因の調査
// セル属性のコードのところに print(leftTableViewList[indexPath.section][indexPath.row]) を加えてデバッグしました。配列から正しく文字列を取り出せていないと思うのですが、原因が理解できませんでした。(勉強不足です。すいません。)

Labelが重なって表示されているようにも見えたので、コメントアウトを行いシミュレーターを起動したりして試行錯誤してみたのですが、解決策が見つかりませんでした。

以下、デバッグの結果になります。

a
b
c
d
e
f
g
h
i
j
k
c ←ここがおかしいと思っています。

###該当のソースコード

import

1 2class myTableViewController: UITableViewController { 3 4 // セクション 5 var sections = ["11月28日"] 6 7 // 配列 8 let leftTableViewList:[[String]] = [["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]] 9 10 // 配列 11 let rightTableViewList:[[String]] = [["", "l", "m", "n", "", "", "", "", "", "", ""]] 12 13 // 初期表示 14 override func viewDidLoad() { 15 super.viewDidLoad() 16 17 } 18 19 20 // sectionの数 21 override func numberOfSections(in tableView: UITableView) -> Int { 22 return sections.count 23 } 24 25 // セクション属性 26 override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 27 return sections[section] 28 } 29 30 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 return leftTableViewList[section].count 32 } 33 34 // セルの幅(69に設定) 35 override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 36 return 69 37 } 38 39 // セル属性 40 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 41 let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) 42 43 44 // ラベルとスイッチボタンを配置する処理 45 // 画面全体の幅を取得 46 let screenX = Double(UIScreen.main.bounds.size.width) 47 48 // ラベルを配置決定(左側の項目) 49 let leftLabel : UILabel = UILabel(frame: CGRect(x: 15, y: 25, width:70, height:20)) 50 let leftLabel.text = leftTableViewList[indexPath.section][indexPath.row] 51 // デバッグ用に配置 52 print(leftTableViewList[indexPath.section][indexPath.row]) 53 // 文字の位置設定(左寄せ) 54 leftLabel.textAlignment = NSTextAlignment.left 55 leftLabel.adjustsFontSizeToFitWidth = true 56 // 文字のはみ出し防止 57 leftLabel.minimumScaleFactor = 0.5 58 cell.contentView.addSubview(leftLabel) 59 60 61 // ラベルの配置決定(右側スイッチボタンの上の文字3つ) 62 let rightLabel : UILabel = UILabel(frame: CGRect(x: screenX - 80, y:5, width: 70, height:20)) 63 rightLabel.text = rightTableViewList[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row] 64 rightLabel.textAlignment = NSTextAlignment.center 65 rightLabel.adjustsFontSizeToFitWidth = true 66 rightLabel.minimumScaleFactor = 0.1 67 cell.contentView.addSubview(rightLabel) 68 69 70 // スイッチボタンを宣言 71 let swcBtn: UISwitch = UISwitch(frame: CGRect(x: screenX - 70, y:32, width: 70, height:20)) 72 swcBtn.isOn = false 73 // swh.addTarget(self, action: Selector("onClick:"), for: UIControlEvents.valueChanged) 74 75 // swcBtnを変数に格納 76 let swb1 = swcBtn 77 let swb2 = swcBtn 78 let swb3 = swcBtn 79 80 // rowが1 or 2 or 3の時にスイッチボタンを配置する 81 switch indexPath { 82 83 case [0, 1]: 84 cell.contentView.addSubview(swb1) 85 86 case [0, 2]: 87 cell.contentView.addSubview(swb2) 88 89 case [0, 3]: 90 cell.contentView.addSubview(swb3) 91 92 default: 93 return cell 94 95 96 } 97 98 return cell 99 100 101 102 } 103 104 105 106 107 override func didReceiveMemoryWarning() { 108 super.didReceiveMemoryWarning() 109 110 111 112 } 113 114 115 116}

###補足情報(言語/FW/ツール等のバージョンなど)
開発言語→swift3.0
開発ツール→xcode8

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

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

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

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

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

guest

回答1

0

ベストアンサー

dequeueReusableCell(withIdentifier:for:)は、使用済みのセルをそのまま再利用します。
そのままというのは、前回使用時にaddSubviewしたもの(UILabel/UISwitch)が全てそのまま残っているということです。

ということは、cellForRow(at:)が呼ばれてセルが生成されるたびに、UILabelやUISwitchがaddSubviewされて積み重なっている、というのは理解出来るでしょうか?

とりあえずの解決策として、セル再利用時に、前回使用時のsubviewを全て剥がしてみます。

swift

1let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) 2//subviewを全て剥がす 3cell.contentView.subviews.forEach { 4 $0.removeFromSuperview() 5} 6:

投稿2016/11/28 07:53

fuzzball

総合スコア16731

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

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

reveco

2016/11/28 08:16

dequeueReusableCell(withIdentifier:for:)でセルを再利用するということは知っていましたが、LabelやSwitchも再利用されているとは知りませんでした。 コードを追加したところ、文字化けしなくなりました。貴重なアドバイスとコードをありがとうございます!
fuzzball

2016/11/28 08:28

このままだとセルの再利用をしている意味が全くありませんので、初回利用時のみLabel/Switchの生成を行うような修正にチャレンジしてみてはどうでしょうか。(初回かどうかの判定方法を考えてみて下さい) Storyboardを使っているなら、カスタムセルについて調べるのが良いと思います。
reveco

2016/11/29 06:31

再びのアドバイスありがとうございます。LabelやswitchButtonなどの部品関係は全てコードのみで処理を行っています。 初回かどうかの判定方法も少し難しそうですが、勉強しながら策を練っていきたいと思います。また壁に当たりましたら質問させていただきます。 貴重なアドバイスありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問