카테고리 없음
FestaGram) AlertController
500beckwon
2020. 5. 11. 16:10
alert을 만들때 하나하나 alertAction만들어서 넣기가 좀 그래서 구글링을 통해 새로운 방식의 alert을 만들어보려고한당.
import UIKit
enum SelectedType: String {
case option = "안내"
case logout = "로그아웃"
case block = "차단"
case report = "신고"
}
class CommonService {
static let shread = CommonService()
var orderSelect: SelectedType = .option
}
일단 새로운 파일을 만들고
import UIKit
import Firebase
fileprivate let postRef = Firestore.firestore().posts
fileprivate let storeRef = Storage.storage()
struct AlertComponents {
var title: String?
var message: String?
var actions: [UIAlertAction]
var completion: (() -> Void)?
init(title:String?,
message: String? = nil,
actions: [AlertActionComponent],
completion: (() -> Void)? = nil) {
self.title = title
self.message = message
self.completion = completion
self.actions = actions.map {
UIAlertAction(title: $0.title, style: $0.style, handler: $0.hander)
}
}
}
struct AlertActionComponent {
var title: String
var style: UIAlertAction.Style
var hander: ((UIAlertAction) -> Void)?
init(title:String, style: UIAlertAction.Style = .default, handler: ((UIAlertAction)-> Void)?) {
self.title = title
self.style = style
self.hander = handler
}
}
protocol AlertPresentable {
var optionAlertComponents: AlertComponents { get }
func selectAlertType(by orderSelect: SelectedType) -> AlertComponents
}
extension AlertPresentable where Self: UIViewController {
private var alertTitle: String? {
return optionAlertComponents.title
}
private var message: String? {
return optionAlertComponents.message
}
private var actions: [UIAlertAction] {
return optionAlertComponents.actions
}
var alertStyle: UIAlertController.Style {
return .actionSheet
}
private var completion: (() -> Void)? {
return optionAlertComponents.completion
}
func presentAlert(_ alertStyle: UIAlertController.Style) {
let alert = UIAlertController(title: alertTitle, message: message, preferredStyle: alertStyle)
actions.forEach { alert.addAction($0) }
present(alert, animated: true, completion: completion)
}
}
이렇게 프로토콜을 이용해서 Controller파일에 프로토콜을 채택하면 다양하게 이용이 가능한데
extension ViewPostingController {
func selectAlertType(by orderSelect: SelectedType) -> AlertComponents {
let _postUID = post?.userUID ?? ""
switch orderSelect {
case .option:
let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
CommonService.shread.orderSelect = .option
}
let rePostAction = AlertActionComponent(title: "수정", style: .default) { _ in
}
let deleteAction = AlertActionComponent(title: "삭제", style: .default) { _ in
}
let blockAction = AlertActionComponent(title: "차단(Block)", style: .destructive) { _ in
CommonService.shread.orderSelect = .block
self.presentAlert(.alert)
}
let report = AlertActionComponent(title: "신고(Report)", style: .default) { _ in
CommonService.shread.orderSelect = .report
self.presentAlert(.alert)
}
if _postUID == CurrentUID.shread.currentUID {
let alert = AlertComponents(title: "관리", message: "관리할 항목을 선택해주세요.", actions: [cancel,deleteAction,rePostAction])
return alert
} else {
let alert = AlertComponents(title: "설정", message: "관련 항목을 선택해주세요.", actions: [cancel,blockAction,report])
return alert
}
case .block:
return blockAction()
case .report:
return reportAction()
case .logout:
return outAction()
}
}
func blockAction() -> AlertComponents {
let blockMessage = "차단을 하시면 해당 유저에 관련된 모든 것을 두번 다시 볼 수 없게 됩니다. 차단하시겠습니까?"
let okAction = AlertActionComponent(title: "차단", style: .destructive) { _ in
//FIXME: 차단 기능
CommonService.shread.orderSelect = .option
print("차단")
}
let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
CommonService.shread.orderSelect = .option
}
let alert = AlertComponents(title: "차단", message: blockMessage, actions:[okAction,cancel])
return alert
}
func outAction() -> AlertComponents {
let outMessage = "대화방을 나가면 대화 기록이 없어집니다. 나가시겠습니까?"
let okAction = AlertActionComponent(title: "나가기", style: .destructive) { _ in
//FIXME: 나가기 기능
CommonService.shread.orderSelect = .option
print("나가기")
}
let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
CommonService.shread.orderSelect = .option
}
let alert = AlertComponents(title: "차단", message: outMessage, actions:[okAction,cancel])
return alert
}
func reportAction() -> AlertComponents {
let reportMessage = "신고를 하시면 24시간 내에 신고된 컨텐츠의 내용을 확인한 후 제재가 결정됩니다."
let okAction = AlertActionComponent(title: "신고", style: .destructive) { _ in
//FIXME: 신고기능
CommonService.shread.orderSelect = .option
print("신고")
}
let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
CommonService.shread.orderSelect = .option
}
let alert = AlertComponents(title: "차단", message: reportMessage, actions:[okAction,cancel])
return alert
}
}
코드가 더 길어진거 같은데 좀더 줄여서 세련되고 있어보이고 머리 잘돌아가게 만들필요가 있을 것 같다 현재
이 AlertCustom은 3 Controller에 사용중인데 UIViewcontroller에 선언하자니 좀 너무 많이 잡아먹고 해당 옵션들도
유저가 본인이냐 타인이냐 어떤 컨트롤러냐에 따라 다르게 나와야 해서 좀더 고민해서 고칠 필요가 있는 것 같다
alert을 선택했을 때 enum타입을 다시 설정해줘야 기존의 항목들이 나오는것도 더 번거로워 보이고...
일단 이렇게 만들고 좀더 생각해 봐야겠다.