위와 같은 형태를 ActionSheet라고 하고, 저렇게 커스텀된 요소들이 있지만, 좀 더 커스텀이 되기를 원합니다.
예를 들면 이렇게 생겼습니다.
선택된 항목은 Bold도 되어야 하고, 배경도 흰색으로 꽉 채워야 합니다. 예쁘게 만들어 보겠습니다.
누르면 아래에서 위로 애니메이션 되며 뷰를 띄워줘야 합니다. 스토리보드로는 한계가 있습니다
(스토리보드로 이런거 어떻게 만들어야할지 사실 감이 잘 안오기도 합니다)
따라서 코드로 만들어 보았습니다. CollectionView를 사용하였습니다.
class Setting: NSObject {
let name: SettingName
init(name: SettingName) {
self.name = name
}
}
Setting에 필요한 객체를 미리 enum이나 Struct로 선언해서 보관해 두고 사용할 것입니다.
Swift File 이름은 SettingLauncher입니다.
아래 생성할 CollectionView가
이런 화면을 만들어낼 것입니다.
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
// 빈 CollectionView 선언, 있다가 CellSize를 부여할 것
cv.backgroundColor = UIColor.white
return cv
}()
CollectionView를 선언하고, 아래와 같이 사이즈를 줍니다. CellHeight는 50입니다.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let setting = self.settings[indexPath.item]
handleDismiss(setting: setting)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return settings.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SettingCell
let setting = settings[indexPath.item]
cell.setting = setting
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: cellHeight)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
또한, 코드로 구현한 Layout은
override init() {
super.init()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(SettingCell.self, forCellWithReuseIdentifier: cellId)
}
와 같이 register, datasource, delegate를 선언해주어야 합니다.
CollectionView를 만들었으니, 이제 Action을 추가하겠습니다.
네비게이션 바의 버튼을 눌렀을 때, Action이 수행되도록 하겠습니다.
func showSettings() {
//show menu
// if let window = UIApplication.shared.keyWindow {
// shard.keyWindow가 Deprecated 되었다고 합니닷 아래와 같이 사용
if let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {
blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
window.addSubview(blackView) //@@1
window.addSubview(collectionView) //@@2
let height: CGFloat = CGFloat(settings.count) * cellHeight
let y = window.frame.height - height
// y : collectionView가 그려지는 시작 위치
collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
blackView.frame = window.frame
blackView.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.blackView.alpha = 1
self.collectionView.frame = CGRect(x:0, y: y, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
}, completion: nil)
}
}
showSettings()는 CollectionView를 addSubView()로 넣고,
BlackView라는 View는 배경을 어둡게 해주는 역할을 합니다. 이렇게 됩니다.
해당 배경이 Opacity가 있는 BlackView입니다. UIView.Animate()에서는 BlackView의 Alpha와,
CollectionView의 frame이 변경됨을 알 수 있습니다.
또한, showSetting()은 호출이 되어야 하는데, 어느 버튼에서나 Selector를 사용해서 호출해내면 됩니다.
저는 위에서 이야기한 바와 같이 NavigationItem의 Button을 이용할 것입니다.
NavigationBar는 원래 ViewController파일에 존재하므로, ( 제 경우 - HomeViewController )
HomeVC에서
lazy var settingsLauncher: SettingsLauncher = {
let launcher = SettingsLauncher()
launcher.homeController = self
return launcher
}()
,
func setupNavBarButtons() {
let moreButton = UIBarButtonItem(image: UIImage(named: "nav_more_icon")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(handleMore))
navigationItem.rightBarButtonItem = moreButton
}
@objc func handleMore() {
settingsLauncher.showSettings()
}
를 만들어주면, 버튼을 누를 경우 showSettings()가 실행이 됩니다.
전체 코드는 깃헙에 업로드!
감사합니다.
'iOS' 카테고리의 다른 글
[iOS] Calendar (1) (0) | 2020.04.25 |
---|---|
[iOS] LinkPresentation (0) | 2020.04.18 |
[Crecker, iOS] PageViewController (android : ViewPager) (2) | 2020.04.04 |
[Crecker,iOS] Swift ViewPager 구성 (4) | 2020.03.28 |
[iOS] 8주차) Coredata (0) | 2020.03.21 |