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

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

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

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

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

Swift

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

Q&A

解決済

1回答

965閲覧

セルをタップすると画像の大きさが変動してしまうのを解決したいです。

ken_sasaki2

総合スコア4

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

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

Swift

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

0グッド

0クリップ

投稿2020/12/26 07:36

現在開発中のアプリにてcell.imageViewに画像を表示しております。
そこで一つご相談があります。

動作確認動画

https://i.gyazo.com/b56962c53afd63efa06b2e3c1c041722.mp4

問題点

動作確認動画にもあるようにセルをタップすると画像の大きさが変動してしまう。

実装コード

//セルを構築する際に呼ばれるメソッド

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //RSSで取得したニュースの値が入る let newsItem = joySelectionArray[indexPath.row] //セルのスタイルを設定 let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell" ) //サムネイルのインスタンス(画像URL, 待機画像, 画像キャッシュ) let thumbnailURL = URL(string: joySelectionArray[indexPath.row].image!.description) let placeholder = UIImage(named: "placeholder") //サムネイルの反映 cell.imageView?.kf.setImage(with: thumbnailURL, placeholder: placeholder, options: [.transition(.fade(0.2))]) //サムネイルのサイズを統一(黄金比) cell.imageView?.image = cell.imageView?.image?.resize(_size: CGSize(width: 130, height: 80)) //セルを化粧 cell.backgroundColor = UIColor.white cell.textLabel?.text = newsItem.title cell.textLabel?.font = UIFont.systemFont(ofSize: 15.0, weight: .medium) cell.textLabel?.textColor = UIColor(hex: "333") cell.textLabel?.numberOfLines = 2 //空のセルを削除 tableView.tableFooterView = UIView(frame: .zero) //インスタンス作成 let dateFormatter = DateFormatter() //フォーマット設定 dateFormatter.dateFormat = "yyyy'年'M'月'd'日('EEEEE') 'H'時'm'分's'秒'" //ロケール設定(日本語・日本国固定) dateFormatter.locale = Locale(identifier: "ja_JP") //タイムゾーン設定(日本標準時固定) dateFormatter.timeZone = TimeZone(identifier: "Asia/Tokyo") //Date型 → string型 let pubDateString = dateFormatter.string(from: Date()) //セルのサブタイトル cell.detailTextLabel?.text = pubDateString cell.detailTextLabel?.textColor = UIColor.gray return cell } //セルをタップした時呼ばれるメソッド override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { //タップ時の選択色の常灯を消す tableView.deselectRow(at: indexPath as IndexPath, animated: true) //WebViewControllerのインスタンス作成 let webViewController = WebViewController() //WebViewのNavigationControllerを定義 let webViewNavigation = UINavigationController(rootViewController: webViewController) //WebViewをフルスクリーンに webViewNavigation.modalPresentationStyle = .fullScreen //タップしたセルを検知 let tapCell = joySelectionArray[indexPath.row] //検知したセルのurlを取得 UserDefaults.standard.set(tapCell.url, forKey: "url") //webViewControllerへ遷移 present(webViewNavigation, animated: true) }
extension UIImage { //比率を保持してリサイズ func resize(_size: CGSize) -> UIImage { let widthRatio = _size.width / self.size.width let heightRatio = _size.height / self.size.height let ratio = (widthRatio < heightRatio) ? widthRatio : heightRatio let resizedSize = CGSize(width: (self.size.width * ratio), height: (self.size.height * ratio)) UIGraphicsBeginImageContextWithOptions(_size, false, 0.0) draw(in: CGRect(x: (_size.width - resizedSize.width) / 2, y: (_size.height - resizedSize.height) / 2, width: resizedSize.width, height: resizedSize.height)) let resizedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resizedImage ?? self; } }

仮説と対応

・仮説
→ 明確にサイズを指定していなかった為、指定する必要があると仮説。
・仮設に対する対応
→ 実装コードにもあるようにextensionを扱ってサイズを統一した。

仮設検証

状況は変わらず。ただ、タップする以前のサイズは意図したサイズに指定することができた。
もし分かる方がいらっしゃいましたらご協力のほどよろしくお願いいたします!

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

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

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

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

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

guest

回答1

0

ベストアンサー

Kingfisher を使っていると思いますが、とりあえず解決させるのであれば、

Swift

1 let processor = ResizingImageProcessor(referenceSize: CGSize(width: 130, height: 80)) 2 cell.imageView?.kf.setImage(with: thumbnailURL, 3 placeholder: placeholder, 4 options: [ 5 .processor(processor), 6 .transition(.fade(0.2)) 7 ]) 8 //サムネイルのサイズを統一(黄金比) 9 cell.imageView?.image = cell.imageView?.image?.resize(_size: CGSize(width: 130, height: 80))

こんな感じで ResizingImageProcessor(referenceSize:) を使えば解決すると思います。

しかし、これは適切な例ではないと思います(かなり強引な解決方法です)。

Cell に Subtitle のセルを使って、そこに配置された ImageView にリサイズさせた画像を入れていますが、Subtitle の ImageView に対する拘束(サイズ設定など)の詳細がわからない以上、今後また意図しない挙動を示す可能性が考えられます。

また、Cell を表示するたびに新しいセルを生成しているため生成コストが高く、表示数が多くなるとスムーズは動きが実現できなくなる危険性もあります(なので、通常はカスタムセルを登録し、それを dequeue する方法で使いまわします)。

コストが高い、という意味では、セル内で毎回 Dateformatter のインスタンスを生成するのも避けた方が良いと言われています。

ということで、根本的に解決させたいのであれば、カスタムセルを作る(StoryBoard で Cell をカスタムにし、そこに ImageView などを配置し、制約(Constraint)を適切につける)、あるいは Cell の xib ファイルを作ると言った方法を採用すべきかと思います。

ちなみに、私も最近 Kingfisher の 遅延読み込み + キャッシュ + プレースホルダ の組み合わせで TableView を使ったアプリをつくってみましたが、その例だとクリックした際に画像のサイズが変わるということはありませんでした。

投稿2020/12/26 11:58

TsukubaDepot

総合スコア5086

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問