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

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

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

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

1428閲覧

SwiftにてTableViewCellなどの細かい位置調整がしたい

Atsushi_Kygo

総合スコア7

iOS

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/07/15 12:17

編集2020/07/15 13:36

GoogleKeepのような見た目をSwiftで作成したい

現在SwiftでGoogleKeepのようなアプリ(Todoリストアプリ)を作成しようとしています。
TableViewCell・TableViewHeaderの位置調整を細かくしたいのですが、どこを変更すれば良いかがわかりません。
(チェックボックスなどは一旦置いときます)
初心者のため初歩的な質問かもしれませんがよろしくお願いします。

【現在のシミュレーター↓】
![現在のシミュレーター
【完成形のデザイン↓】
完成形のデザイン

発生している問題・エラーメッセージ

// viewForHeaderInSectionメソッド内にて // この記述が適用されない&この記述が適切か分からない(セクションタイトルの位置を変更しようとしている) sectionTitle.frame = CGRect(x:50, y:10, width: 100, height: 50)

該当のソースコード

Swift

1import UIKit 2 3class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate { 4 5 @IBOutlet weak var tableView: UITableView! 6 @IBOutlet weak var textField: UITextField! 7 8 var notSelectedList = ["リストアイテム1", "リストアイテム2"] 9 var selectedList = [String]() 10 var thisSectionTitle = "タイトル" 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 tableView.delegate = self 16 tableView.dataSource = self 17 textField.delegate = self 18 } 19 20 21 // セクションの数 22 func numberOfSections(in tableView: UITableView) -> Int { 23 return 2 24 } 25 26 27 // セクションタイトルの微調整 28 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 29 30 let sectionTitle: UILabel = UILabel() 31 sectionTitle.backgroundColor = .white 32 sectionTitle.textColor = .black 33 // 以下のコードが適用されない 34 // sectionTitle.frame = CGRect(x:50, y:10, width: 100, height: 50) 35 36 if section == 0 { 37 sectionTitle.text = thisSectionTitle 38 tableView.sectionHeaderHeight = 40 39 sectionTitle.font = UIFont.systemFont(ofSize: 28.0) 40 } else { 41 sectionTitle.text = "選択中のアイテム ▼" 42 } 43 44 return sectionTitle 45 } 46 47 48 // セルの個数 49 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 50 if section == 0 { 51 return notSelectedList.count 52 } else { 53 return selectedList.count 54 } 55 } 56 57 58 // セルの設定 59 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 60 61 // identifierに紐づいたセルを取得し、変数cellに代入 62 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 63 64 if indexPath.section == 0 { 65 cell.textLabel!.text = notSelectedList[indexPath.row] 66 } else { 67 cell.textLabel!.text = selectedList[indexPath.row] 68 } 69 70 return cell 71 72 } 73} 74 75

試したこと・調べたこと

・layoutMarginsについて調べた
(マージンを0にする記事が多く、よく分からなかった)

・UIEdgeInsetsについて調べた
(記述方法等がよく分からなかった)

・カスタムセルについて調べた
(調べた限りではカスタムセルにするほどでもないと予想)

補足情報(FW/ツールのバージョンなど)

Swift version 5.2.4

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

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

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

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

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

TsukubaDepot

2020/07/15 12:52

実現されたいことが具体的に想像できないので(細かくしたいのであれば尚更)、できれば図を用いて(現時点でのスクリーンキャプチャに手書きなどでこのへんをこうしたい、など)説明していただければ助かりますのでご検討ください。
Atsushi_Kygo

2020/07/15 13:37

修正依頼ありがとうございます。
guest

回答1

0

ベストアンサー

実際に GoogleKeep をインストールしてみました。
GoogleKeep がどのような技術を使って実現されているのかはわかりませんが

・カスタムセルについて調べた
(調べた限りではカスタムセルにするほどでもないと予想)

これが一番楽だと思います。

マージンなどを調整する方法もあると思いますが、AutoLayout という技術があるのですから、それを活用した方が楽かと思います。

基本的には

  • タイトルを表示するカスタムセル
  • 個別の ToDo を表示するカスタムセル

を作ります。
それぞれのカスタムセル内に必要なラベルやボタンなどを配置し、カスタムセルを基準して制約をつけていけば、セルの生成時に細かい作業を行わなくても思ったような表示ができるのではないでしょうか。

いま簡単に作ってみましたが、

イメージ説明

こんな感じになります。

制約などは次のような感じです。

イメージ説明

作ってしまったので、ソースコードも貼っておきます。

ただ注意していただきたいのは、下記のコードにおけるデータの管理方法は褒められた例ではない、ということです。

データ(オブジェクト)の管理方法はいろいろあるかと思いますが、私は全然勉強が追いついていないのでこんな感じの管理方法となっていますが、それについては是非ご自身で理解を深めていただければと思います。

Swift

1import UIKit 2 3class Item { 4 var isDone = false 5 var itemTitle = "" 6 7 init(itemTitle title: String, done: Bool) { 8 self.itemTitle = title 9 self.isDone = done 10 } 11} 12 13class ToDo { 14 var title = "" 15 var items = [Item]() 16} 17 18class ViewController: UIViewController, UITableViewDataSource { 19 20 @IBOutlet weak var todoListTable: UITableView! 21 var todo = ToDo() 22 23 override func viewDidLoad() { 24 super.viewDidLoad() 25 // Do any additional setup after loading the view. 26 27 todoListTable.dataSource = self 28 29 // 区切り線を消す 30 // 一部だけ消すのであれば 31 // https://qiita.com/takashings/items/693ba4b31d07dbe90778 32 todoListTable.separatorStyle = .none 33 34 // 仮の ToDo を作る 35 todo.title = "きょうやること" 36 todo.items.append(Item(itemTitle: "朝起きる", done: true)) 37 todo.items.append(Item(itemTitle: "歯を磨く", done: false)) 38 todo.items.append(Item(itemTitle: "マスクをする", done: true)) 39 } 40 41 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 42 // 表示したいセルはToDo の 「要素数 + タイトル」 43 let itemCount = todo.items.count + 1 44 45 return itemCount 46 } 47 48 // MARK: セルの表示行数によって使うセルを切り替える 49 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 50 if indexPath.row == 0 { 51 // タイトル 52 let headerCell = tableView.dequeueReusableCell(withIdentifier: "Header", for: indexPath) as! HeaderTableViewCell 53 headerCell.titleLabel.text = todo.title 54 55 return headerCell 56 } else { 57 // 個別の ToDo 58 let itemCell = tableView.dequeueReusableCell(withIdentifier: "Item", for: indexPath) as! ItemTableViewCell 59 let item = todo.items[indexPath.row - 1] 60 itemCell.item = item 61 62 itemCell.updateCell() 63 64 //print("cell: ", indexPath.row) 65 //dump(item) 66 67 return itemCell 68 } 69 } 70} 71 72class HeaderTableViewCell: UITableViewCell { 73 @IBOutlet weak var titleLabel: UILabel! 74 75 override func awakeFromNib() { 76 super.awakeFromNib() 77 // Initialization code 78 } 79 80 override func setSelected(_ selected: Bool, animated: Bool) { 81 super.setSelected(selected, animated: animated) 82 83 // Configure the view for the selected state 84 } 85 86} 87 88class ItemTableViewCell: UITableViewCell { 89 @IBOutlet weak var itemLabel: UILabel! 90 @IBOutlet weak var checkButton: UIButton! 91 92 // MARK: セルにでも個別の ToDo を保持する 93 var item: Item! 94 95 override func awakeFromNib() { 96 super.awakeFromNib() 97 // Initialization code 98 } 99 100 override func setSelected(_ selected: Bool, animated: Bool) { 101 super.setSelected(selected, animated: animated) 102 103 // Configure the view for the selected state 104 } 105 106 // MARK: セルの状態変更 107 func updateCell () { 108 itemLabel.text = item.itemTitle 109 110 if item.isDone { 111 checkButton.setImage(UIImage(systemName: "checkmark.rectangle"), for: .normal) 112 } else { 113 checkButton.setImage(UIImage(systemName: "rectangle"), for: .normal) 114 } 115 } 116 117 // MARK: チェックマークが呼び出された時 118 @IBAction func buttonSelected(_ sender: Any) { 119 //dump(item) 120 item.isDone.toggle() 121 122 // self (つまり、このクラス)の superView は UITableView 123 // UITableView.reloadData() を呼び出している 124 (self.superview as! UITableView).reloadData() 125 } 126}

投稿2020/07/16 03:02

TsukubaDepot

総合スコア5086

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

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

Atsushi_Kygo

2020/07/17 13:10

GoogleKeepのインストールやアプリの作成など何から何まで本当にありがとうございます。 解説等もわかりやすく、非常に参考になりました。 カスタムセルでの開発に取り組んでみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問