멜팅비의 개발 공부

[iOS-Swift] UIPickerView Custom하기 (슬롯머신처럼 만들기) 본문

개발 공부/[iOS 개발]

[iOS-Swift] UIPickerView Custom하기 (슬롯머신처럼 만들기)

멜팅비 2021. 2. 22. 20:04
반응형

현재 개발 중인 앱이 슬롯머신처럼 버튼을 눌렀을 때 랜덤 하게 pick 해주는 기능이 포함되어 있는데

iOS에서 어떻게 구현해야 할지 검색하다가 DateTimePicker처럼 UIPickerView를 이용해서 자동으로 스크롤링되도록 구현하기로 했다.

그래서 UIPickerView를 Custom 하기 위해 필요한 부분들을 정리해봤다.


UIPickerView 사용자 스크롤 막기

- 버튼을 눌렀을 때만 동작하게 만들기 위해서 사용자가 직접 터치하는 부분을 막을 때 사용

pickerView.isUserInteractionEnabled = false

 

UIPickerView 아이템 높이 변경(row height)

- 설정하고자 하는 높이를 return 하면 된다.

func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 60
}

 

UIPickerView indicator 숨기기(hide indicator)

- UIPickerView를 생성하게 되면 selectedRow부분이 회색 바탕으로 표시되거나, 구분선으로 표시가 되는데,

Custom 하기 위해서 이 부분을 숨기는 코드이다.

override func viewDidLayoutSubviews() {
    pickerView.subviews[1].isHidden = true
    
    // 또는
    pickerView.subviews[1].isHidden = true
    pickerView.subviews[2].isHidden = true
}

 

UIPickerView 일정 시간 동안 스크롤되도록(자동 스크롤 느낌)

- self.picker.selectRow(randomRow, inComponent: 0, animated: true)는 랜덤 row로 이동하지만

좀 더 스크롤되다가 멈추는 느낌을 구현하려면 timer를 활용해야 한다. 

 

func trigger() {
      let timer = Timer.scheduledTimer(timeInterval: 0.25, target: self, selector: #selector(scrollRandomly), userInfo: nil, repeats: true);
     
      DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1*NSEC_PER_SEC))/Double(NSEC_PER_SEC)) {
          timer.invalidate()
      }
 }

 func scrollRandomly() {
      let row:Int = Int*random(in: 1..<100)
      self.pickerView.selectRow(row, inComponent: 0, animated: true)
 }

timer를 통해 1초동안 스크롤되다가 멈추도록 구현했다.

trigger()를 버튼 클릭 시 호출해주면 된다. 코드는 stackoverflow에서 찾았고 내 필요에 맞게 수정했다.

왼쪽이 self.picker.selectRow(randomRow, inComponent: 0, animated: true)만 사용했을 경우,

오른쪽이 timer를 통해 스크롤을 구현한 경우

 

 

UIPicerView 선택된 항목 텍스트 색상 변경 (SelectedItem TextColor Change)

- 위 이미지에서 볼 수 있듯이 선택된 항목의 텍스트 색상 변경 코드이다.

var pickerData = [String]()
var selectedRow: Int {
    return pickerView.selectedRow(inComponent: 0)
}

func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
    var color = UIColor.gray

    if row == selectedRow {
        color = UIColor.blue //set custom color 
    } else if selectedRow == row - 1 || selectedRow == row + 1 {
        color = UIColor.black // set custom color
    }

    return NSAttributedString(string: pickerData[row], attributes: [NSAttributedString.Key.foregroundColor: color])
}

 

UIPickerView Loop 되도록

- UIPickerView의 아이템 항목을 loop 되도록 하고 싶을 경우

(PickerView에 들어가는 항목을 많이 만들어서 loop 되는 것처럼 구현하는 방식인 것 같다..)

extension SlotViewController: UIPickerViewDataSource {
  
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count*100
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row % pickerData.count]
    }
    
}

 


Android에서 구현할 때는 요구사항을 충족시킬 수 있는 라이브러리를 찾느라 고생이 많았는데,

iOS에서는 UIPickerView를 통해 해결 할 수 있어서 한결 쉬웠다.

반응형
Comments