UIPickerView depending on first component - ios

So I have a UIPickerView with two components. The first one called "Cupboards", the second "Drawer". They have a one to many relationships in CoreData Cupboards <-->> Drawer. I would like that if I select a Cupboard, only the matching Drawers get displayed. I'm not sure how to get that working with the relationship.
That's what I have for showing the Cupboard:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component==0){
return cupboards.count
}
xxxx
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if(component==0){
return cupboards[row].name
}
xxxx
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
}
}
Thank you in advance
Update:
Got it like that now, but I get no results.
var cupboardDrawers = [Drawer]()
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
let request: NSFetchRequest<Drawer> = Drawer.fetchRequest()
request.predicate = NSPredicate(format: "cupboard == %#", cupboards[row].name!)
do{
let result = try mgdContext.fetch(request)
cupboardDrawers = result
addEatDataPicker.reloadAllComponents()
}catch{
print(error.localizedDescription)
}
}
}

You need to create and update a cupboardDrawers array with the fetching results:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component==0){
return cupboards.count
} else {
return cupboardDrawers.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if(component==0){
return cupboards[row].name
} else {
return cupboardDrawers[row].yourProperty
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
// you can add this part to a separate function and call it here
cupboardDrawers = []
let request = NSFetchRequest<Drawer>(entityName:”Drawer”)
request.predicate = YourPredicate with cupboards[row].name
do {
let items = context.fetch(request)
guard items.count > 0 else {
print(“no items found”)
return
}
cupboardDrawers = items
//reload your picker
} catch {
print(error)
}
}
}

Related

for loop in titleForRow in pickerView not working

I was creating a clock pickerView and used the following:
var countSec = Array(0...10)
var countMin = Array(0...59)
var countHour = Array(0...59)
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0{
for count in countSec {
return "\(count)"
}
}else{
for count in countMin{
return "\(count)"
}
}
return nil
}
But when I run, all the data was 0s.
Don't use loops in titleForRow. Just return the appropriate value for the requested row.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return "\(countSec[row])"
} else {
return "\(countMin[row])"
}
}

uipickerview index out if range

I'm trying to learn to code Swift and recently I faced a bug which is so embarrassing.
I have 2 textfield which both are connected to a picker view.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if EntCity.isEditing
{
return MainCities[row].name
}
return MainJ[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if EntState.isFirstResponder
{
EntState.text = MainJ[row].name
Global_Addresses.global_address.cityID_fromState = MainJ[row].id
GetCities()
}
if EntCity.isEditing
{
if (EntState.text?.isEmpty)!
{
DispatchQueue.main.async {
self.DisplayMessage(UserMessage: "ابتدا استان را انتخاب کنید")
}
}
else
{
EntCity.text = MainCities[row].name
Global_Addresses.global_address.smallCityID = MainCities[row].id
}
}
EntState.text = MainJ[row].name
Global_Addresses.global_address.cityID_fromState = MainJ[row].id
GetCities()
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return MainCities.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return MainCities[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
EntCity.text = MainCities[row].name
Global_Addresses.global_address.smallCityID = MainCities[row].id
print("?????????????????????")
print(Global_Addresses.global_address.smallCityID)
}
}
the code works fine and both textfield can show the data in the picker view to choose. these textfield are connected, it means that
you have to choose one of the rows in textfield number 1 to get the data for textfield number 2 . when i choose the first data , and select the second textfield to choose the second one , it works fine untill i choose of those data which their row number is bigger than the first textfield
and as you can see i have declared that if it select first or second textfield to return different number for row!

number input with UiPickerView

In my use case I would like to add in numbers consisting of 4 digits, like in the image. The first digit should be 0 or 1.
My code so far is:
func numberOfComponents(in weightPickerView: UIPickerView) -> Int {
return 4
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return loopingMargin * numbers.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return numbers[row % numbers.count]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
digits[component] = row % numbers.count
let weightString = "\(digits[0])\(digits[1])\(digits[2])\(digits[3])"
weightField.text = weightString
}
How can I achieve that?
Considering:
let numbers = [2,10,10,10]
var digits = [0,0,0,0]
Update your delegate methods like this:
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return numbers[component]
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(row)
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
digits[component] = row
let weightString = "\(digits[0])\(digits[1])\(digits[2])\(digits[3])"
weightField.text = weightString
}
You can try
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component == 0)
{
return 2
}
else
{
return loopingMargin * numbers.count
}
}

I can't add a UIPickerview for gender in a registration form

I am creating a registration form and I have to include the gender inside a text field using a picker view. However, I am getting question marks instead of male and female.
Here is my code:
#IBOutlet weak var genderfield: UITextField!
let pickerView = UIPickerView()
let gender1 = ["Male", "Female"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return gender1.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender1[row]
}
func pickerView(_ pickerView:UIPickerView,didSelectRow row: Int,forComponent component: Int){
genderfield.text = gender1[row]
genderfield.resignFirstResponder()
}
And in ViewDidLoad:
pickerView.delegate = self
pickerView.dataSource = self
genderfield.inputView = pickerView
I don't think there is something wrong in my code. I have been googling for hours.
You get question marks because you have the wrong signature on your titleForRow delegate method.
Change:
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender1[row]
}
to:
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender1[row]
}
Note the addition of _ just after the (.
You can not added UIPickerViewDelegate, UIPickerViewDataSource.
so when you add delegate and data source of picker view its work fine.
like this:
extension RegisterVC : UIPickerViewDelegate, UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return gender1.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender1[row]
}
func pickerView(_ pickerView:UIPickerView,didSelectRow row: Int,inComponent component: Int){
genderfield.text = gender1[row]
genderfield.resignFirstResponder()
}

Populating UIPickerView with CoreData attribute -- Swift4 IOS11

I have tried so much what I found here on StackOverflow like this, but nothing worked for me… I would like to use the Values from a Core Data Attribute for a PickerView.
My Entity is called "Task" with the Attribute "name".
I know I need to fetch the data and I already did that, but I don’t know how to just get the values of my Attribute as an Array.
At the moment I use A UIPickerView like this:
var var1 = [""]
let var2 = ["---","1","2","3","4","5","6","7"]
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if(component==0){
return var1[row]
}
return var2[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component==0){
return var1.count
}
return var2.count
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int{
return 2
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
test1 = var1[row]
}
test2 = var2[row]
}
This is how I fetch my Data for an UITableView:
// GetData
func getData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
tasks = try context.fetch(Task.fetchRequest())
}
catch{
print("Fetching Failed")
}
}
So I hope someone can help me, fetching the right attribute. I'm really new to Swift/Programming I started with swift 3 Days ago.. so a little code example would be great for me to understand how it works... Thanks in advance
EDIT: (How I populate the data in table view)
var tasks : [Task] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let task = tasks[indexPath.row]
cell.textLabel?.text = task.name
return cell
}
Update:
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> Task {
return tasks[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return tasks.count
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
test1 = tasks[row]
}

Resources