how to have "hour", "minute", "second" text behind UIPickView

23 Views Asked by At

I'm making an app with a countdown timer feature.

I want to show UIPickView like this.enter image description here

And this is my app enter image description here

I tried using UIDatePicker but it doesn't include seconds

I tried using UILabel to add them but when running on different devices they are out of position.

I am a new coder, please help me!

func displayTimePickerAlert() {let alertController = UIAlertController(title: "Select countdown time", message: "\n\n\n\n\n\n", preferredStyle: .actionSheet)
    timePickerView.dataSource = self
    timePickerView.delegate = self
    timePickerView.frame = CGRect(x: 8, y: 20, width: alertController.view.bounds.width - 20, height: 140)
    alertController.view.addSubview(timePickerView)
    
    
    let okAction = UIAlertAction(title: "OK", style: .default) { \[weak self\] (\_) in
   
        let selectedHour = self?.selectedHour ?? 0
        let selectedMinute = self?.selectedMinute ?? 0
        let selectedSecond = self?.selectedSecond ?? 0
        self?.remainingTime = (selectedHour \* 3600) + (selectedMinute \* 60) + selectedSecond
    }
    alertController.addAction(okAction)
    present(alertController, animated: true, completion: nil)
}

extension CountdownController: UIPickerViewDataSource, UIPickerViewDelegate {

func numberOfComponents(in pickerView: UIPickerView) -\> Int {
    return 3
}

func pickerView(\_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -\> Int {
    switch component {
    case 0: // Giờ
        return hours.count
    case 1: // Phút
        return minutes.count
    case 2: // Giây
        return seconds.count
    default:
        return 0
    }
}

func pickerView(\_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -\> String? {
    switch component {
    case 0:
        return String(hours\[row\])
    case 1:
        return String(minutes\[row\])
    case 2:
        return String(seconds\[row\])
    default:
        return ""
    }
}

func pickerView(\_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if component == 0 {
        selectedHour = hours\[row\]
    } else if component == 1 {
        selectedMinute = minutes\[row\]
    } else if component == 2 {
        selectedSecond = seconds\[row\]
    }
    updateCountdownLabel()
}

}

1

There are 1 best solutions below

0
On

You can try to customise it like this.

class TimerSelectViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    pickerView.delegate = self
}

@IBOutlet var pickerView: UIPickerView!

var hour: Int = 0
var minutes: Int = 0
var seconds: Int = 0

}

 extension TimerSelectViewController: UIPickerViewDelegate, UIPickerViewDataSource {

     func numberOfComponents(in pickerView: UIPickerView) -> Int {
         return 3
     }

     func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
         switch component {
         case 0:
             return 25
         case 1, 2:
             return 60
         default:
             return 0
         }
     }

     func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
         return pickerView.frame.size.width/3
     }

     func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
         switch component {
         case 0:
             return "\(row) Hour"
         case 1:
             return "\(row) Minute"
         case 2:
             return "\(row) Second"
         default:
             return ""
         }
     }
     func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         switch component {
         case 0:
             hour = row
         case 1:
             minutes = row
         case 2:
             seconds = row
         default:
             break;
         }
     }
 }