본문 바로가기

Tech/iOS

[iOS] Day 25 - UIPickerView & WebView

728x90

언젠가는 완벽하게

UX UI 코드까지 완벽하게

오늘도 달려보자


UIPickerView

이전 게시물에 잠깐 등장했던 UIPickerView 저번에는 Storyboard로 구현했지만 이번에는 코드로 구현하겠다

 

class LottoViewController: UIViewController {
    
    @IBOutlet weak var numberTextField: UITextField!
  
    var lottoPickerView = UIPickerView()
    
    let lottoList: [Int] = Array(1...1025).reversed()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        numberTextField.tintColor = .clear
        numberTextField.inputView = lottoPickerView
        
        lottoPickerView.delegate = self
        lottoPickerView.dataSource = self
        
        numberTextField.delegate = self

       
    }
}


extension LottoViewController: UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        //옵션 휠 돌아갈때 몇개?
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        //component 갯수
        return lottoList.count
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //멈추는 시점
        numberTextField.text = "\(lottoList[row])회차"
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        //각각의 열마다 어떤 글자?
        return "\(lottoList[row])회차"
    }
    
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        textField.isUserInteractionEnabled = false
        return true
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        textField.isUserInteractionEnabled = true
    }
    
}

UIPickerView를 만드는 코드다

구조는 텍스트뷰가 상단에 있고 UIPickerView가 하단에 있는 모양이다

생각해보자 

View가 실행되면 UIPickerView가 위치한 하단에 또 UIPickerView가 올라오는 현상이 발생한다

-> 이를 방지하려 viewDidLoad에서 textField.inputView = lottoPickerView(UIPickerView의 인스턴스 변수) 지정하여 textField에서 필요할 때 마다 UIPickerView를 호출하는 역할을 할 수 있다

 

delegate? dataSource?

collectionView, tableView할 때 Storyboard에서 구현한 후 IBOutlet 연결하면 알아서 적용됐지만 코드로 구현할 때는 꼭 선언을 해주어야 코드가 작동된다

왜 textField는 dataSource는 선언 안할까?

쉽게 생각하면 Delegate는 editingStyleForRowAt, didSelectRowAt과 같은 스와이프 편집 기능이나 셀 클릭 기능 등 기능의 역할을 해준다

DataSource는 numberOfRowsInSection, cellForRowAt 섹션 내 셀 갯수, 셀 디자인 및 데이터 처리 같은 User에게 데이터를 어떻게 보여주는지에 대한 역할을 담당한다 

textField의 경우 textField에 text가 나타나는 구조라 데이터를 User에게 어떤 방식으로 보여줄지는 이미 정해져 있으므로 기능의 역할을 하는 Delegate만 선언한다

 

Extension?

지금까지 봐 왔던 Extension의 위치는 항상 새로운 파일에 선언을 한 후 가져왔는데 기존과는 다르게 같은 영역 하단에 Extension이 있다

뷰 객체마다 필요한 프로토콜 익스텐션으로 나눠준다

따로 파일을 만들고 익스텐션을 넣는 것은 가능하지만, 프로토콜이 많아질수록 파일이 많아져서 controller 안에 만드는게 좋다

 


WebView

import WebKit을 꼭 해주어야 한다

 func openWebPage(url: String) {
        //유효한 URL인지 확인
        guard let url = URL(string: url) else {
            print("Invaild URL")
            return
        }
        let request = URLRequest(url: url)
        webView.load(request)
        //skeletonView library
    }

함수를 실행하면 웹뷰에 url을 불러올 수 있다


ToolBar

View위에 툴바를 얹어서 사용한다

Library를 보면 2가지 toolBarItem이 있는데

Fixed Space Bar Button -> 고정된 공간을 두고 아이템 배치

Flexible Space Bar Button -> flexible한 공간을 두고 아이템 배치(대표적으로 오른쪽 끝에 버튼을 놓고 싶은 경우 사용) 

 

'Tech > iOS' 카테고리의 다른 글

[iOS]Day 26 - Notification  (0) 2022.07.29
[iOS] Day 25 - Protocol  (0) 2022.07.28
[iOS] Day 24 - Property Observer  (0) 2022.07.27
[iOS] Day 23 - Computed Property  (0) 2022.07.26
[iOS] Day 22 - Xcode Tip, bundle File 생성 방법  (0) 2022.07.25