// MARK: - 사용할 picker 만들기
func createPicker() {
// toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
// bar button
let doneBtnPeriod = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePreseedPeriod))
toolbar.setItems([doneBtnPeriod], animated: true)
// assign toolbar
alarmPeriodTextField.inputAccessoryView = toolbar
// assign picker to the textField
alarmPeriodTextField.inputView = periodPicker
// datePicker mode
alarmTimePicker.preferredDatePickerStyle = .wheels
}
@objc func donePreseedPeriod() {
self.view.endEditing(true)
enableCompleteBtn()
}
// MARK: - picker component 수정
extension InputDetailVC: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return 1
}
else {
return 3
}
}
}
extension InputDetailVC: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return "every"
}
else if component == 1 {
return num[row]
}
return period[row]
}
(개인정보는 모자이크 처리 했습니다!)
// MARK: - 검색한 후 필터링 된 데이터를 보여주기 위해 필요한 변수
var filteredData: [Friend]!
var nameTextFrom: String = ""
var phoneNumFrom: String = ""
//MARK: - UISearchBar 속성 변경 함수
func setSearchBar() {
searchBar.placeholder = "친구 검색"
searchBar.setImage(UIImage(named: "icn_search_box"), for: UISearchBar.Icon.search, state: .normal)
searchBar.layer.borderWidth = 0
searchBar.searchBarStyle = .minimal
searchBar.setSearchFieldBackgroundImage(UIImage(named: "search_box"), for: .normal)
searchBar.sizeToFit()
searchBar.searchTextField.sizeToFit()
searchBar.searchTextField.textColor = UIColor.black
searchBar.searchTextField.font = UIFont.init(name: "NotoSansCJKKR-Regular", size: 14)
}
// UISearchBar delegate
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = []
//검색창에 입력하지 않으면 tableView를 원래대로 보여준다
if searchText == "" {
filteredData = friendList
}
else {
for friend in friendList {
//cell의 변수가 searchText에 포함되면
if friend.name.contains(searchText) {
filteredData.append(contentsOf: [
Friend(name: friend.name, phoneNumber: friend.phoneNumber, selected: friend.selected)])
}
else if friend.phoneNumber.contains(searchText) {
filteredData.append(contentsOf: [Friend(name: friend.name, phoneNumber: friend.phoneNumber, selected: friend.selected)])
}
}
}
self.tableView.reloadData()
}
let callObserver = CXCallObserver()
var didDetectOutgoingCall = false
class PopUpContactVC: UIViewController {
//MARK: - Call Material
func showCallAlert() {
guard let url = NSURL(string: "tel://" + UserDefaults.standard.string(forKey: "selectedFriendPhoneData")!),
UIApplication.shared.canOpenURL(url as URL) else {
return
}
callObserver.setDelegate(self, queue: nil)
didDetectOutgoingCall = false
//we only want to add the observer after the alert is displayed,
//that's why we're using asyncAfter(deadline:)
UIApplication.shared.open(url as URL, options: [:]) { [weak self] success in
if success {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self?.addNotifObserver()
}
}
}
}
func addNotifObserver() {
let selector = #selector(appDidBecomeActive)
let notifName = UIApplication.didBecomeActiveNotification
NotificationCenter.default.addObserver(self, selector: selector, name: notifName, object: nil)
}
@objc func appDidBecomeActive() {
//if callObserver(_:callChanged:) doesn't get called after a certain time,
//the call dialog was not shown - so the Cancel button was pressed
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
if !(self?.didDetectOutgoingCall ?? true) {
print("Cancel button pressed")
}
}
}
@IBAction func calling(_ sender: Any) {
showCallAlert()
}
}
//MARK: -Protocol Extension
/// 1
extension PopUpContactVC: CXCallObserverDelegate{
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
/// 통화를 하게 되면
if call.isOutgoing && !didDetectOutgoingCall {
didDetectOutgoingCall = true
guard let pvc = self.presentingViewController else {return}
self.dismiss(animated: true){
let storyBoard: UIStoryboard = UIStoryboard(name: "Review", bundle: nil)
if let vc = storyBoard.instantiateViewController(withIdentifier: "ReviewVC") as? ReviewVC{
vc.modalPresentationStyle = .fullScreen
pvc.present(vc, animated: true, completion: nil)
}
}
print("Call button pressed")
}
}
}
이슈1
isHidden 메소드를 이용하여 false로 해도 해당 뷰의 Space는 그대로 남아있었기 때문에 키워드, 리뷰가 없어도 첫 화면처럼 완성이 되지 않았었다.
하지만 StackView를 이용하여 해결했는데, StackView의 특성 상 내부의 Contents가 줄어들면서 StackView전체가 같이 줄어들기 때문에 아래의 코드처럼 Contraints 값을 조정했을 때 원하는 모습대로 뷰가 나올 수 있었다.
/// 키워드, 리뷰의 입력 여부에 따른 메모 뷰 크기 조정
func memoHeightMode(idx: Int){
/// 키워드 미입력 시
if keywordForCV.count == 0 {
calendarKeywordCollectionView.isHidden = true
keywordCVTopAnchor.constant = 0
}else{
calendarKeywordCollectionView.isHidden = false
keywordCVTopAnchor.constant = 14
}
/// 메모 미입력 시
if fetchCalendar[idx].review.count < 1 || fetchCalendar[idx].review == "" {
keywordCVBotAnchor.constant = 0
memoTextLabel.isHidden = true
}else{
keywordCVBotAnchor.constant = 10
memoTextLabel.isHidden = false
}
/// 키워드,메모 미입력 시
if (fetchCalendar[idx].review.count < 1 || fetchCalendar[idx].review == "") && keywordForCV.count == 0 {
memoBtnTopAnchor.constant = 22
memoBtn.isHidden = true
}else{
memoBtnTopAnchor.constant = 17
memoBtn.isHidden = false
}
}