swift custom popup - 재사용가능한 팝업
xib - 디자인
popupVC.swift - 공통 팝업 뷰컨트롤러
//
// PopupVC.swift
// Po
//
// Created by k on 2021/08/09.
//
import UIKit
/// 팝업 타입
enum PopupTpye {
case alarm //라벨 + 닫기
case textField //라벨 + 텍스트 + (닫기,ok)
case closeAndOk //라벨 + (닫기,ok)
}
class PopupVC: UIViewController {
/// 팝업 뷰
@IBOutlet weak var popUpView: UIView!
/// 라벨
@IBOutlet weak var labelContent: UILabel!
/// 텍스트 필드
@IBOutlet weak var textFieldContent: UITextField!
/// 취소 버튼
@IBOutlet weak var cancelBtn: UIButton!
/// ok 버튼
@IBOutlet weak var okBtn: UIButton!
/// 취소, ok 버튼 감싼 View
@IBOutlet weak var buttonWrapperView: UIView!
/// 완전 취소 - 한개 버튼
@IBOutlet weak var cancelOneBtn: UIButton!
/// 취소 or 확인 중 선택된 버튼 0 : 취소, 1 확인
var clickedBtn = ""
///팝업 타입
var popupType :PopupTpye = .alarm
///팝업 텍스트
var popupText = ""
/// 취소 버튼 이름
var cancelBtnName = ""
/// ok 버튼 이름
var okBtnName = ""
/// 취소 단독 버튼 이름
var cancelOneBtnName = ""
override func viewDidLoad() {
super.viewDidLoad()
self.popUpView.layer.cornerRadius = 10
switch popupType {
case .alarm:
print("alarm")
labelContent.text = popupText
cancelOneBtn.setTitle(cancelOneBtnName, for: .normal) //단독취소버튼 이름 set
textFieldContent.isHidden = true //텍스트필드 숨김
buttonWrapperView.isHidden = true //확인버튼, 취소버튼 wrapper view 숨김
case .textField:
print("textField")
labelContent.text = popupText
okBtn.setTitle(okBtnName, for: .normal) //확인버튼 이름 set
cancelBtn.setTitle(cancelBtnName, for: .normal) //취소버튼 이름 set
cancelOneBtn.isHidden = true //단독취소버튼 숨김
case .closeAndOk:
print("closeAndOk")
labelContent.text = popupText
okBtn.setTitle(okBtnName, for: .normal) //확인버튼 이름 set
cancelBtn.setTitle(cancelBtnName, for: .normal) //취소버튼 이름 set
textFieldContent.isHidden = true //텍스트필드 숨김
cancelOneBtn.isHidden = true //단독취소버튼 숨김
}
}
/// 취소버튼 이벤트와 확인 ok 이벤트
@IBAction func clickCancelAndOkBtn(_ sender: UIButton) {
/// 클릭한 버튼 : 0 취소, 1 확인
clickedBtn = "\(sender.tag)"
NotificationCenter.default.post(name: .getPopupEventResult,object: self)
}
/// 완전 취소
@IBAction func clickCancelOneBtn(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
// willMove -> It appears on the parent screen.
override func willMove(toParent parent: UIViewController?) {
print(#function)
if let parent = parent as UIViewController? {
print(parent)
}
}
// It appears on the parent screen. -> didMove
override func didMove(toParent parent: UIViewController?) {
print(#function)
if let parent = parent as UIViewController? {
print(parent)
}
}
//https://medium.com/@jang.wangsu/swift-containerview-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-ee2ed07ec4e8
}
controllCenter.swit - 싱글톤으로 공통팝업 열여주기
//
// ControllCenter.swift
// Po
//
// Created by k on 2021/08/09.
//
import UIKit
import Foundation
class ControllCenter {
static let shared = ControllCenter()
var testVal = ""
let window = UIApplication.shared.windows.first { $0.isKeyWindow}
/**
- Author: k
- Date:
- Parameters:
- popupText: 알림내용 text
- cancelOneBtnName: 닫기or 확인 버튼 명
- vc : 팝업 델리게이트 메소드 대리자
- Returns:
- Note: 알람 팝업 띄우기
*/
public func showAlarmPopup(vc:UIViewController, popupText:String , cancelOneBtnName :String){
print("showBasicPopup")
/// 최상위 뷰컨트롤러
if let rootVc = window?.rootViewController{
let visibleController = self.getRootViewController(vc: rootVc)
///팝업
let popvc = PopupVC(nibName: "PopupVC", bundle: nil)
popvc.modalPresentationStyle = .overCurrentContext
popvc.popupText = popupText
popvc.popupType = .alarm
popvc.cancelOneBtnName = cancelOneBtnName
visibleController?.present(popvc, animated: true, completion: nil)
}
}
/**
- Author: k
- Date:
- Parameters:
- popupText: 알림내용 text
- okBtnName: 확인 버튼 명
- cancelBtnName: 닫기 버튼 명
- vc : 팝업 델리게이트 메소드 대리자
- Returns:
- Note: 텍스트필드 입력 팝업 띄우기
*/
public func showInputTextFieldPopup(vc:UIViewController, popupText:String , okBtnName :String , cancelBtnName :String){
print("showInputTextFieldPopup")
/// 최상위 뷰컨트롤러
if let rootVc = window?.rootViewController{
let visibleController = self.getRootViewController(vc: rootVc)
///팝업
let popvc = PopupVC(nibName: "PopupVC", bundle: nil)
popvc.modalPresentationStyle = .overCurrentContext
popvc.popupText = popupText
popvc.popupType = .textField
popvc.okBtnName = okBtnName
popvc.cancelBtnName = cancelBtnName
visibleController?.present(popvc, animated: true, completion: nil)
}
}
/**
- Author: k
- Date:
- Parameters:
- popupText: 알림내용 text
- okBtnName: 확인 버튼 명
- cancelBtnName: 닫기 버튼 명
- vc : 팝업 델리게이트 메소드 대리자
- Returns:
- Note: 닫기, 확인 팝업 띄우기
*/
public func showOkAndClosePopup(vc:UIViewController, popupText:String , okBtnName :String , cancelBtnName :String){
print("showInputTextFieldPopup")
/// 최상위 뷰컨트롤러
if let rootVc = window?.rootViewController{
let visibleController = self.getRootViewController(vc: rootVc)
///팝업
let popvc = PopupVC(nibName: "PopupVC", bundle: nil)
popvc.modalPresentationStyle = .overCurrentContext
popvc.popupText = popupText
popvc.popupType = .closeAndOk
popvc.okBtnName = okBtnName
popvc.cancelBtnName = cancelBtnName
visibleController?.present(popvc, animated: true, completion: nil)
}
}
/**
# getRootViewController
- Author: k
- Date:
- Parameters:
- vc: rootViewController 혹은 UITapViewController
- Returns: UIViewController?
- Note: vc내에서 가장 최상위에 있는 뷰컨트롤러 반환
*/
public func getRootViewController(vc:UIViewController) ->UIViewController?{
///[1] 네비게이션 컨트롤러
if let nc = vc as? UINavigationController {
if let vcOfnavController = nc.visibleViewController {
return self.getRootViewController(vc: vcOfnavController)
}
///[2] 탭뷰 컨트롤러
}else if let tc = vc as? UITabBarController {
if let tcOfnavControler = tc.selectedViewController {
return self.getRootViewController(vc: tcOfnavControler)
}
///[3] 뷰 컨트롤러
}else{
if let pvc = vc.presentedViewController{
return self.getRootViewController(vc: pvc)
}else {
return vc
}
}
return nil
}
}
팝업띄우기
//
// LoginViewController.swift
// QuestionIOS
//
// Created by k2 on 2021/04/11.
//
import UIKit
import RealmSwift
class LoginViewController: UIViewController {
/// 옵저버
var observer: NSObjectProtocol?
/// 코디네이터
var coordinator: SiginCoordinator?
@IBOutlet weak var emailTxtfield: UITextField!
@IBOutlet weak var pwTxtfield: UITextField!
@IBOutlet weak var emailPwCheckMsg: UILabel!
@IBOutlet weak var loginBtn: UIButton!
@IBOutlet weak var siginBtn: UIButton!
//MARK: 로그인 체크 후 탭바 띄우기
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
/// 로그인 체크 후 탭바 띄우기
self.openMainTabBarController()
///notificaion 옵저버 등록
self.regNotificationObserver()
}
//MARK: 옵저버 등록
/// 옵저버 등록
private func regNotificationObserver(){
///팝업 노티
observer = NotificationCenter.default.addObserver(forName: .getPopupEventResult, object: nil, queue: OperationQueue.main) { notification in
let popUpVC = notification.object as! PopupVC
Log.debug("팝업타입 : \(popUpVC.popupType)" )
Log.debug("눌린버튼 : \(popUpVC.clickedBtn)" )
Log.debug("텍스트내용 : \(popUpVC.textFieldContent.text ?? "")" )
}
}
//MARK: viewDidDisappear
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let observer = observer{
NotificationCenter.default.removeObserver(observer)
}
}
//MARK:테스트 팝업
@IBAction func testPopup(_ sender: UIButton) {
// ControllCenter.shared.showAlarmPopup(vc:self, popupText: "일반 알람...", cancelOneBtnName: "오게이..")
ControllCenter.shared.showInputTextFieldPopup(vc:self, popupText: "텍스트필드 위드 팝업", okBtnName: "오게이", cancelBtnName: "놉")
// ControllCenter.shared.showOkAndClosePopup(vc:self, popupText: "확인, 닫기 팝업....", okBtnName: "응", cancelBtnName: "아냐..")
}
}
*콜백함수로 데이터 전달하기
popupVC.swift
class PopupVC: UIViewController {
/// 팝업 완료 콜백 함수 선언
var callBackFunc: ((_ popupType: PopupTpye ,_ clickedBtn: String ,_ txt: String) -> ())?
/// 취소버튼 이벤트와 확인 ok 이벤트
@IBAction func clickCancelAndOkBtn(_ sender: UIButton) {
/// 클릭한 버튼 : 0 취소, 1 확인
//콜백함수 호출
callBackFunc?(popupType, "\(sender.tag)", textFieldContent.text ?? "")
self.dismiss(animated: true, completion: nil)
}
...
}
ControllCenter.swift
public func showOkAndClosePopup(vc:UIViewController, popupText:String , okBtnName :String , cancelBtnName :String , complete: @escaping (PopupTpye ,String ,String) -> ()){
print("showInputTextFieldPopup")
/// 최상위 뷰컨트롤러
if let rootVc = window?.rootViewController{
let visibleController = self.getRootViewController(vc: rootVc)
///팝업
let popvc = PopupVC(nibName: "PopupVC", bundle: nil)
popvc.modalPresentationStyle = .overCurrentContext
popvc.popupText = popupText
popvc.popupType = .closeAndOk
popvc.okBtnName = okBtnName
popvc.cancelBtnName = cancelBtnName
popvc.callBackFunc = { (popupType , clickedBtn , txt) in
complete(popupType , clickedBtn , txt)
}
visibleController?.present(popvc, animated: true, completion: nil)
}
}
LoginViewController.swift - 호출해서 콜백받기
ControllCenter.shared.showInputTextFieldPopup(vc:self, popupText: "텍스트필드 위드 팝업", okBtnName: "오게이", cancelBtnName: "놉") { (popupType , clickedBtn , txt) in
if popupType == .textField {
}
Log.debug("팝업타입 : \(popupType)" )
Log.debug("눌린버튼 : \(clickedBtn)" )
Log.debug("텍스트내용 : \(txt)" )
}
참고할만한 블로그 - addChild
https://sujinnaljin.medium.com/swift-addchild%EC%9D%98-frame-%EB%AC%B8%EC%A0%9C-961cc2361424
https://minominodomino.github.io/devlog/2019/05/19/ios-ContainerViewController/
'아이폰 개발 > Swift' 카테고리의 다른 글
swift Date 날짜 달력 관련 클래스 정리 (0) | 2021.09.24 |
---|---|
swift - 최상위 ViewController 구하기 (0) | 2021.08.10 |
swift 스위치 - 위치이동 (0) | 2021.08.02 |
swift Dynamic Font (aspect ratio & multiplier & autoshrink) (0) | 2021.08.01 |
swift Popup 2 Align Important (0) | 2021.07.31 |