我用来自bookingInfo
的数据填充UIPickerView,它按预期工作。但是,我需要在UIPickerView中再添加一行,并为其分配一个"默认值"。
要在numberOfRowsInComponent
中执行此操作,请返回bookingInfo.count + 1
问题是我在switch语句中得到的错误索引超出范围。我不确定是不是因为firebase异步检索数据。
class ContactUs: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var currentUid:String!
var dbRef:FIRDatabaseReference!
var bookingInfo = [FireBaseData]() // this array will hold all bookings for the logged in user
@IBOutlet weak var bookingsPickerView: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
bookingsPickerView.delegate = self
bookingsPickerView.dataSource = self
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
self.currentUid = uid
dbRef = FIRDatabase.database().reference().child("Cleaners")
startObservingDB() // observe the database for value changes
}//end of viewDidLoad
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return bookingInfo.count + 1 //if I don't add 1 my code will run properly
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = UILabel(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(300), height: CGFloat(37)))
if bookingInfo.isEmpty == false {
switch row{
case 0...bookingInfo.count:
//Prints index out of range
let booking = self.bookingInfo[row]
label.text = String(booking.BookingNumber) + " " + String(booking.DateAndTime)
default:
label.text = "default Value"
}
}
return label
}
}// end of class ContactUs
extension ContactUs {
//observe firebase at a specific reference for values changes
func startObservingDB() {
dbRef.child(currentUid).child("bookings").observe(.value, with: { (snapshot: FIRDataSnapshot) in
//instance of FireBaseData holding all bookings under currentUid
var newBookingInfo = [FireBaseData]()
//iterate over each booking which is located under 'bookings'
for booking in snapshot.children {
var bookingItem = FireBaseData(snapshot: booking as! FIRDataSnapshot)
newBookingInfo.append(bookingItem)
}
//assign newBookingInfo to global variable
self.bookingInfo = newBookingInfo
//sort the array in place so that the most recent date will appear first
self.bookingInfo.sort(by: {(DateAndTimeObject_1,DateAndTimeObject_2) -> Bool in
DateAndTimeObject_1.TimeStampDateAndTime > DateAndTimeObject_2.TimeStampDateAndTime
})
// after Firebase retrieves all bookings, reload the componets in the picker view so that the methods belonging to protocol UIPickerViewDelegate will be called
self.bookingsPickerView.reloadAllComponents()
}, withCancel: { (Error:Any) in
print("Error firebase \(Error)")
})
} // end of startObservingDB()
}//end of extension
更新
感谢@livtay我的代码有效。我怎么能拥有"其他"当bookingInfo数组不是空的而不是现在显示的最后一行时,第一行的值显示?
我到目前为止的进展。
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = UILabel(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(300), height: CGFloat(37)))
label.textAlignment = .left
if bookingInfo.isEmpty == true {
label.text = "Other"
self.pickerViewTitle = "Other"
} else {
switch row{
case 0...bookingInfo.count - 1:
let booking = self.bookingInfo[row]
self.pickerViewTitle = String(booking.BookingNumber) + " " + String(booking.DateAndTime)
label.text = self.pickerViewTitle
default:
label.text = "Other"
self.pickerViewTitle = "Other"
}
}
return label
}
答案 0 :(得分:1)
尝试更改
case 0...bookingInfo.count:
到
case 0...bookingInfo.count - 1:
因为数组的计数包含0。 例如,如果数组有1个对象,则计数为0 ... 1,但数组中唯一的索引为0。
编辑:问题的第二部分:
在你的switch语句中,将代码放在
下的默认情况下case 0:
然后其余的
case 1...bookingInfo.count:
并且您想要将逻辑更改为:
let booking = self.bookingInfo[row - 1]