UIAlertController를 만들고 title과 action button중간에 textField를 넣을 것이다.
let alert = UIAlertController(title: nil, message: "사용자님 이름을 입력해주세요", preferredStyle: .alert)
let btn = UIAlertAction(title:확인,style:.default)
{
(_) in
//추후 사용자의 tf 입력시 alert를 종료하면서 다른 view의 label text 갱신할 거에요.
}
alert.addAction(btn)
기본적인 alert 생성하고
- 첫번째의 경우는
//컨테이너 뷰
let centerView = UIView()
//텍스트 필드
let tf = UITextField()
tf.frame = CGRect(x:0,y:0,width: self.view.frame.width,height: 30)
tf.text = "홍길동"
centerView.addSubView(tf)
alert.view.addSubview(centerView)
present(alert,animated:false)
이렇게 할 경우
이렇게 된다..
UIAlertController의 title 이 nil이고 message가 String이 있지만, 반대로 title에 "사용자님 이름을..."으로 해도 centerView의 뷰는 저렇게 0,0에 위치한다.
title, message도 nil 처리 할 경우 여전히 좌표가 0,0이다.
여기서 궁금한 것은 centerView의 frame을 지정해주지 않았는데, subView는 centerView에 감싸져있는데 centerView는 subView의 CGPoint를 따라가는 것일까?..
또한 왜 UIView는 적어도 tf의 크기만큼의 영역을 갖추지 못하는 것일까?..
alert의 view에 addSubview로 추가했기 때문에 당연한 결과이다.
여기서 centerView의 constraint를 지정해준다면..
NSLayoutConstraint.activate([
centerView.bottomAnchor.constraint(equalTo: alert.view.bottomAnchor, constant: -200),
centerView.heightAnchor.constraint(equalToConstant: 100)
])
이런식으로 바뀌게 된다.
근데 계속 시도를 해보니 이것보단 UIViewController()를 사용하는게 더 좋은 방안인 것 같다. alert의 center 좌표가 이상해 지는 것 같다. alert의 title이나 message, OK 버튼의 인스턴스나 위치를 얻고 싶었는데 어려웠다. 그래서 textfield의 위치를 정하기가 수작업이아닌 이상.. 나에게는 어려웠다.
때에 따라서는 그냥 alert또한 UIAlertController()를 사용하는게 아닌
아예 UIView들로 구성된 틀 안에 label과 button, textfield를 직접 지정해 주면서 Alert처럼 만들었을 때.. 더 쉽게 다룰 수 있을 것 같다. 그래서 현재 UIAlertController에서 UIView를 사용하는 것은 pass...
- 두번째의 경우는 UIViewController()를 넣는 것이다.
let centerVC = UIViewController()
let tf = UITextField()
tf.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 20)
tf.text = "홍길동"
centerVC.view.addSubView(tf)
alert.view.addSubview(centerVC.view)
이 경우도 위에서 UIView로 선언한 경우와 같이 된다.
alert.setValue(centerVC,forKey: "contentViewController")
를 추가하면
이렇게 된다. forkey에 다른 값을 지정해 주면 에러가 발생한다. 그 이유는 contentViewController key값은 apple api에서 정해진 키 값이라고 한다.
contentViewController가 너무 궁금해서 여러 분들에게 조언을 구했는데 알 수 있었다.
setValue를 통해 알림창에 내가 커스텀으로 구현한 UIViewController를 등록할 수 있다. 여기서 중요한것은 위에서 한 UIView와 달리 UIViewController()를 통해 알림창을 커스텀으로 구현하고 setValue(_:forKey:"contentViewController")를 이용한다면 alert의 title과 action버튼 사이에 내가 커스텀으로 정의한 뷰컨트롤러가 끼워져서 구현이 된다.
그래서 콘텐츠 뷰 컨트롤러 영역(숨겨진 영역)이라 하나보다(꼼꼼한 재은씨 swift p 393)
여기서 content.view의 frame을 조절하면 텍스트 필드의 크기에 맞게 줄을까?
content.view.frame = CGRect(x: 0, y: 0, width: tf.frame.width, height: tf.frame.height)
줄지 않고 그대로 그림3 과 같다.
content.preferredContentSize = CGSize(width: tf.frame.width, height: tf.frame.height)
frame이 아닌 preferredContentSize을 해야 textfield의 사이즈가 조절이 된 content가 된다.
추가적으로 textField의 layer등을 설정하면
tf.textAlignment = .center
tf.backgroundColor = .white
tf.layer.cornerRadius = 3
tf.layer.borderColor = UIColor.lightGray.cgColor
tf.layer.borderWidth = 0.3
요런식의 알림창이 된다.
전체적인 코드는
let alert = UIAlertController(title:"사용자님의 이름을 입력해주세요.", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title:"OK",style: .default)
{
(_) in
//확인 버튼 이후 실행해야 할것,,
}
contents = UIViewController()
let tf : UITextField =
{
let myTf = UITextField()
myTf.frame = CGRect(x: 0 ,y:0,width:alert.view.frame.width/2 , height: 30)
myTf.text = "홍길동"
myTf.textAlignment = NSTextAlignment.center
myTf.backgroundColor = .white
myTf.layer.cornerRadius = 3
myTf.layer.borderColor = UIColor.lightGray.cgColor
myTf.layer.borderWidth = 0.3
return myTf
}()
centerVC.view.addSubview(tf)
centerVC.preferredContentSize = CGSize(width: tf.frame.width, height: tf.frame.height)
alert.view.addSubview(centerVC.view)
alert.setValue(centerVC, forKey: "contentViewController")
self.present(alert,animated: true)