dotrikunの日記

日々マンガを読んだりプログラムを書いたりしています。

UITableViewCellに付け外し可能なチェックマークを置く時の話

この記事はSansan Advent Calendar 2016の16日目のやつです。

仕事でiOS8のサポートがまだまだ切れなくてUIStackViewを使えないから、UITableViewCellの小ネタでもどうぞ。

概要

AutoLayout対応してるUITableViewCellに、 UITableViewCellAccessoryTypeで付け外しするチェックマークを実現して失敗したお話。

UITableViewCellにチェックマーク置きたい

リストセルの選択状態を表現するために、セルの右端にチェックマークを出したい時があります。

f:id:dotrikun:20161214182702p:plain

UITableViewCellにはaccessoryTypeという気の利いたプロパティが用意されていて、 定義されたEnumを指定するだけでいい感じのチェックマークを表示することができます。

typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) {
    UITableViewCellAccessoryNone,                                                      // don't show any accessory view
    UITableViewCellAccessoryDisclosureIndicator,                                       // regular chevron. doesn't track
    UITableViewCellAccessoryDetailDisclosureButton __TVOS_PROHIBITED,                 // info button w/ chevron. tracks
    UITableViewCellAccessoryCheckmark,                                                 // checkmark. doesn't track
    UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0)  __TVOS_PROHIBITED // info button. tracks
};

なにが起こったか

先に書いたやり方でチェックマークの表示/非表示を切り換えを実装すると、セルの横幅に合わせたラベルが伸び縮みしてキモい。

f:id:dotrikun:20161214182500g:plain

なんでこうなるかというと、accessoryTypeに UITableViewCellAccessoryNone 以外を指定するとContentViewの横幅が自動的に狭まるから。 LabelはAutoLayoutでContentViewの右端からマージン取ってるので、ContentViewの幅が変わるとみょんみょんしてしまう。

結論

付け外し可能なチェックマークを実装したい場合、 accessoryType は使わずにUITableViewCellのContentViewに自前でチェックマーク画像のimageViewを置いてレイアウトを組みましょう!ということです。

(みょんみょんするのを気にしない場合はその限りではない)