[iOS] UICellAccessory 종류 알아보기

탑꾸? 🤷🏻‍♀️ 아니 셀꾸요 🙆🏻‍♀️

들어가기 전에

cell.accessories = [ 
.checkmark(),
.delete(),
.reorder()
]

UICellAccessory

cell.accessories = [
.delete(),
.delete(),
]
Thread 1: "Accessories array contains more than one system accessory of the same type. Duplicate accessories: <UICellAccessoryDelete: 0x600002ab6080> <UICellAccessoryDelete: 0x600002ab60c0>"
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Emoji> { (cell, indexPath, emoji) in
var contentConfiguration = UIListContentConfiguration.valueCell()
contentConfiguration.text = emoji.text
cell.contentConfiguration = contentConfiguration
}
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Emoji> { (cell, indexPath, emoji) in
var contentConfiguration = UIListContentConfiguration.valueCell()
contentConfiguration.text = emoji.text
cell.contentConfiguration = contentConfiguration
cell.accessories = [
.outlineDisclosure(displayed: .always),
.disclosureIndicator(displayed: .always),
.delete(displayed: .always),
.reorder(displayed: .always),
.checkmark(displayed: .always),
.insert(displayed: .always),
.multiselect(displayed: .always),
.label(text: "naljin", displayed: .always),
.detail( displayed: .always),
.popUpMenu(
UIMenu(children: [
UIAction(title: "첫번째", handler: { _ in }),
UIAction(title: "두번째", handler: { _ in })
]),
displayed: .always)
]
}

delete

static func delete(
displayed: UICellAccessory.DisplayedState = .whenEditing,
options: UICellAccessory.DeleteOptions = DeleteOptions(),
actionHandler: UICellAccessory.ActionHandler? = nil
) -> UICellAccessory

displayed

  • always - accessory 가 언제나 표시됩니다.
  • whenEditing - cell 이 editing mode 일때만 accessory 가 표시됩니다.
  • whenNotEditing - cell 이 editing mode 가 아닐때만 accessory 가 표시됩니다.
cell.accessories = [.delete()]

options

UICellAccessory.DeleteOptions.init(
isHidden: Bool? = nil,
reservedLayoutWidth: UICellAccessory.LayoutDimension? = nil,
tintColor: UIColor? = nil,
backgroundColor: UIColor? = nil
)
UICellAccessory.delete(displayed: .always,
options: .init(tintColor: .red,
backgroundColor: .green))
UICellAccessory.delete(displayed: .always,
options: .init(isHidden: true))
  • actual - 액세서리 레이아웃은 실제 치수(dimension)를 사용
  • standard - 액세서리 레이아웃은 액세서리에 대한 시스템 표준 레이아웃 dimension 를 사용
  • custom(CGFloat) - 액세서리 레이아웃은 사용자가 지정한 값을 사용

actionHandler

typealias UICellAccessory.ActionHandler = () -> Void
cell.accessories = [
.delete(displayed: .always,
options: .init(isHidden: false,
reservedLayoutWidth: .standard,
tintColor: .red,
backgroundColor: .green),
actionHandler: {
print("삭제 버튼 클릭됨")
})
]

insert

static func insert(
displayed: UICellAccessory.DisplayedState = .whenEditing,
options: UICellAccessory.InsertOptions = InsertOptions(),
actionHandler: UICellAccessory.ActionHandler? = nil
) -> UICellAccessory
UICellAccessory.InsertOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?,
backgroundColor: UIColor?
)

multiselect

static func multiselect(
displayed: UICellAccessory.DisplayedState = .whenEditing,
options: UICellAccessory.MultiselectOptions = MultiselectOptions()
) -> UICellAccessory
cell.accessories = [.multiselect()]
collectionView.allowsSelectionDuringEditing = true
collectionView.allowsMultipleSelectionDuringEditing = true
static func multiselect(
displayed: UICellAccessory.DisplayedState = .whenEditing,
options: UICellAccessory.MultiselectOptions = MultiselectOptions()
) -> UICellAccessory
UICellAccessory.MultiselectOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?,
backgroundColor: UIColor?
)

label

static func label(
text: String,
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.LabelOptions = LabelOptions()
) -> UICellAccessory
UICellAccessory.LabelOptions.init(
isHidden: Bool? = nil,
reservedLayoutWidth: UICellAccessory.LayoutDimension? = nil,
tintColor: UIColor? = nil,
font: UIFont? = nil,
adjustsFontForContentSizeCategory: Bool? = nil
)

checkmark

재준아 너는 모르잖아 초록색..?
static func checkmark(
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.CheckmarkOptions = CheckmarkOptions()
) -> UICellAccessory
UICellAccessory.CheckmarkOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?
)

detail

static func detail(
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.DetailOptions = DetailOptions(),
actionHandler: UICellAccessory.ActionHandler? = nil
) -> UICellAccessory
UICellAccessory.DetailOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?
)

popUpMenu

static func popUpMenu(
_ menu: UIMenu,
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.PopUpMenuOptions = PopUpMenuOptions(),
selectedElementDidChangeHandler: UICellAccessory.MenuSelectedElementDidChangeHandler? = nil
) -> UICellAccessory
UICellAccessory.popUpMenu(
UIMenu(children: [
UIAction(title: "첫번째", handler: { action in print("첫번째 클릭")}),
UIAction(title: "두번째", handler: { action in print("두번째 클릭")})
])
)
UICellAccessory.PopUpMenuOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?
)
typealias UICellAccessory.MenuSelectedElementDidChangeHandler = (UIMenu) -> Void
cell.accessories = [
.multiselect(displayed: .always),
.popUpMenu(
UIMenu(children: [
UIAction(title: "첫번째", handler: { action in print("첫번째 클릭")}),
UIAction(title: "두번째", handler: { action in print("두번째 클릭")})
])
)
]

disclosureIndicator

static func disclosureIndicator(
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.DisclosureIndicatorOptions = DisclosureIndicatorOptions()
) -> UICellAccessory
UICellAccessory.DisclosureIndicatorOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?
)

outlineDisclosure

맨 첫번째 셀을 주목해주세요
static func outlineDisclosure(
displayed: UICellAccessory.DisplayedState = .always,
options: UICellAccessory.OutlineDisclosureOptions = OutlineDisclosureOptions(),
actionHandler: UICellAccessory.ActionHandler? = nil
) -> UICellAccessory
UICellAccessory.DisclosureIndicatorOptions.init(
style: UICellAccessory.OutlineDisclosureOptions.Style?,
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?
)
  • cell - 중첩된 children 이 있는 선택 가능한 셀에 사용할 스타일. 이 스타일을 사용하면 outline disclosure 액세서리를 클릭하는 경우에만 expansion 상태가 변경됨. cell 자체를 클릭하면 item 에 대한 선택이 됨.
  • header - 섹션 헤더에 사용할 스타일. 이 스타일을 사용하면 cell 의 어느 곳을 클릭하든 expansion 상태가 변경됨. 따라서 이 스타일을 사용하면 cell 자체는 selectable 하지 않게 됨.
  • automatic - 셀의 configuration 이 섹션 헤더인지 여부에 따라 시스템이 자동으로 스타일을 결정

reorder

dataSource.reorderingHandlers.canReorderItem = { item in return true }
dataSource.reorderingHandlers.didReorder = { transaction in
// 구현
}
static func reorder(
displayed: UICellAccessory.DisplayedState = .whenEditing,
options: UICellAccessory.ReorderOptions = ReorderOptions()
) -> UICellAccessory
UICellAccessory.ReorderOptions.init(
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?,
showsVerticalSeparator: Bool?
)
cell.accessories = [
.checkmark(),
.reorder(displayed: .always,
options: .init(showsVerticalSeparator: false)
)
]

custom

let myView = UIView(frame: CGRect(origin: .zero,
size: CGSize(width: 10, height: 10)))
myView.backgroundColor = .red
cell.accessories = [
.customView(configuration: .init(customView: myView,
placement: .leading()))
]
static func customView(configuration: UICellAccessory.CustomViewConfiguration) -> UICellAccessory
init(customView: UIView, 
placement: UICellAccessory.Placement,
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?,
maintainsFixedSize: Bool?)
case leading(displayed: UICellAccessory.DisplayedState, at: UICellAccessory.Placement.Position)
case trailing(displayed: UICellAccessory.DisplayedState, at: UICellAccessory.Placement.Position)
UICellAccessory.customView(configuration: .init(customView: myView,
placement: .leading()))
case leading(
displayed: UICellAccessory.DisplayedState = .always,
at: UICellAccessory.Placement.Position = { $0.count }
)
typealias UICellAccessory.Placement.Position = (_ accessories: [UICellAccessory]) -> Int
cell.accessories = [
.insert(displayed: .always),
.customView(configuration: .init(customView: myView,
placement: .leading())),
.multiselect(displayed:.always)

]
case trailing(
displayed: UICellAccessory.DisplayedState = .always,
at: UICellAccessory.Placement.Position = { _ in 0 }
)
cell.accessories = [
.checkmark(),
.customView(configuration: .init(customView: myView,
placement: .trailing())),
.reorder(displayed: .always)
]
static func position(after: UICellAccessory) -> UICellAccessory.Placement.Position
static func position(before: UICellAccessory) -> UICellAccessory.Placement.Position
UICellAccessory.customView(configuration: .init(customView: myView,
placement: .leading(at: UICellAccessory.Placement.position(after: .insert()))))
cell.accessories = [
.insert(displayed: .always),
.delete(displayed: .always),
.customView(configuration: .init(customView: myView,
placement: .leading(at: UICellAccessory.Placement.position(after: .delete()))))
]
cell.accessories = [
.insert(displayed: .always),
.delete(displayed: .always),
.customView(configuration: .init(customView: myView,
placement: .leading(at: UICellAccessory.Placement.position(after: .multiselect()))))
]
cell.accessories = [
.insert(displayed: .always),
.delete(displayed: .always),
.customView(configuration: .init(customView: myView,
placement: .leading(at: UICellAccessory.Placement.position(before: .multiselect()))))
]
cell.accessories = [
.insert(displayed: .always),
.delete(displayed: .always),
.checkmark(displayed: .always),
.customView(configuration: .init(customView: myView,
placement: .leading(at: UICellAccessory.Placement.position(after: .checkmark()))))
]
position(after: .checkmark()) / position(before: .checkmark())
init(customView: UIView, 
placement: UICellAccessory.Placement,
isHidden: Bool?,
reservedLayoutWidth: UICellAccessory.LayoutDimension?,
tintColor: UIColor?,
maintainsFixedSize: Bool?)

마무리

참고

--

--

 https://github.com/sujinnaljin/TIL

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store