2014-12-24 3 views
21

У меня есть 2 UIPickerController на одном из контроллеров View. Я могу заставить его работать, но когда я добавляю второй, мое приложение падает. Вот код, который я использую для одного выбора:Как использовать 2 UIPickerView в одном контроллере просмотра?

import UIKit 

class RegisterJobPosition: UIViewController, UIPickerViewDelegate{ 

@IBOutlet weak var positionLabel: UILabel! 

var position = ["Lifeguard", "Instructor", "Supervisor"] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
}  

func numberOfComponentsInPickerView(PickerView: UIPickerView!) -> Int 
{ 
    return 1 
} 

func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int 
{ 
    return position.count 
} 

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! 
{ 
    return position[row] 
} 

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 

    positionLabel.text = position[row] 
} 
} 

Теперь, как я могу заставить второй контроллер работать? Скажем, мой второй PickerView называется location (другой называется position). Я попытался дублировать код в методах PickerView для location, но он не работает.

Я использую Swift.

+0

Вам понадобится способ отличить их от двух, если ваш контроллер просмотра является единственным делегатом для взаимодействия с пользователем. Можете ли вы опубликовать код, который вы используете, чтобы отличить их? – andrewcbancroft

+0

Я просто дублирую код. Например, в методе numberOfRowsInComponent я просто положил: return location.count – dom999999

+0

Эта часть имеет смысл. Но как вы программно выясняете, какой экземпляр сборщика вы возвращаете? Если у вас есть два экземпляра сборщика, отправляющих сообщения на ваш единственный контроллер представления (делегат), вам нужен способ определить сборщиков, чтобы вы могли сделать соответствующую логику филиала и вернуть правильный счет для правильного выбора. – andrewcbancroft

ответ

17

Основываясь на информации, которую я имею в вопросе, я бы сказал, что вам необходимо настроить методы делегирования данных &, чтобы обрабатывать возможность различать, какой экземпляр сборщика вызывает их.

Using the tag property на вид подборщика есть одна стратегия.

Должны быть какие-либо инструкции if/else или switch в методах, которые имеют разную логику, в зависимости от того, на какой ссылке ссылается местоположение или позиция.

+1

Что касается операторов if/else, как бы я мог получить переменную, чтобы стать значением, которое указывает местоположение или выбор позиции? – dom999999

+0

Итак, если вы установите тег на сборщиках в раскадровке, вы можете проверить его в методе обратного вызова. Вы видите, что первым параметром метода является pickerView? Вы можете проверить pickerView.tag и выполнить правильную логику на основе корреляции тега с вашим пользовательским интерфейсом и вашим массивом данных. – andrewcbancroft

48

Вот мое решение: - на раскадровку, добавить 2 PickerView к вашему View - установить 1-й picker's бирку # 1 & # 2 для 2-го сборщика под Attributes Inspector - CTRL + перетащить из каждый подборщик на значок верхнего желтого View Controller и выберите dataSource.Repeate тот же выбирающий делегат - repeate выше для другого сборщика тоже - добавить pickerview & pickerviewdelegation к классу ViewController:

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate { 
  • в классе ViewController, создавать пустые массивы для сборщиков:

    var picker1Options = [] 
    var picker2Options = [] 
    
  • на viewDidLoad() метод, заполнить массивы с содержимым:

    picker1Options = ["Option 1","Option 2","Option 3","Option 4","Option 5"] 
    picker2Options = ["Item 1","Item 2","Item 3","Item 4","Item 5"] 
    
  • реализации методов pickerview делегат &:

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
        return 1 
    } 
    
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
        if (pickerView.tag == 1){ 
         return picker1Options.count 
        }else{ 
         return picker2Options.count 
        } 
    } 
    
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! { 
        if (pickerView.tag == 1){ 
         return "\(picker1Options[row])" 
        }else{ 
         return "\(picker2Options[row])" 
        } 
    } 
    

Наслаждайтесь, получайте удовольствие и выразить свое счастье с признаком положительности.

+1

Спасибо за предложение тега, которые действительно помогают мне много использовать несколько picker.I получили решение сейчас. –

+0

Это отводит мне голову от того, насколько сложно заполнить несколько PickerViews в том же ViewController. На Android это супер просто. –

+1

Lazar K, это очень ненавистный комментарий. Это не проще и сложнее. Это совсем другая стратегия. На Android вы бы (или должны) использовать разные адаптеры для разных Spinners. На самом деле вы можете использовать разные источники данных и делегаты на iOS. Я бы на самом деле предложил это в ответ –

0

Мой фон в Android, но мой ответ очень оОП.Я хотел бы предложить создание различных классов для реализации DataSource и делегат вроде этого:

class PositionDataSourceDelegate : NSObject, UIPickerViewDelegate, UIPickerViewDataSource { 
    var position = ["Lifeguard", "Instructor", "Supervisor"] 
    var selectedPosition : String? 

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return position.count 
    } 

    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 
     return position[row] 
    } 

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     selectedPosition = position[row] 
    } 
} 

, а затем еще один для Местоположение:

class LocationDataSourceDelegate : NSObject, UIPickerViewDelegate, UIPickerViewDataSource { 
    var location = ["Up", "Down", "Everywhere"] 
    var selectedLocation : String? 

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return location.count 
    } 

    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 
     return location[row] 
    } 

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     selectedLocation = location[row] 
    } 
} 

то в вашем RegisterJobPosition вам нужно создать экземпляр каждого из них:

let positionDSD = PositionDataSourceDelegate() 
let locationDSD = LocationDataSourceDelegate() 

и назначить их сборщиков, как это:

positionPicker.dataSource = positionDSD 
positionPicker.delegate = positionDSD 
locationPicker.dataSource = locationDSD 
locationPicker.delegate = locationDSD 

и вы можете получить доступ к выбранной позиции и местоположение с помощью:

positionDSD.selectedPosition 
locationDSD.selectedLocation 

Надеется, что это помогает вам и другие, и я также надеюсь на некоторые конструктивные замечания о том, почему это не «Swifty»

+0

Это хорошее решение для OO, но на самом деле это практически не работает - я новичок iOS, но пытаюсь решить эту проблему весь день, и мне кажется, что UIPickerViewDelegate/DataSource также должен быть UIViewController. Простой NSObject не работает. – Fishbreath

0

Я думаю, что самая большая проблема и отличие от Java заключается в том, что Java легко позволяет передавать атрибуты через конструктор. например вы можете объявить класс LocationDataSourceDelegate как общий и вызвать его genericDataSourceDelegate и сделать конструктор accept и Array public genericDataSourceDelegate (String data []) и иметь возможность сделать один класс, где можно просто создать объекты. Вы просто создаете экземпляр и передаете местоположение конструктору, например, genericDataSourceDelegate (location)

Проблема с вашей моделью потребует создать столько классов делегатов в одной программе, которая является напряжением для вашего компилятора.

1

Я нашел это для работы.

class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { 

    @IBOutlet weak var textbox1: UILabel! 
    @IBOutlet weak var textbox2: UILabel! 

    @IBOutlet weak var dropdown1: UIPickerView! 
    @IBOutlet weak var dropdown2: UIPickerView! 

    var age = ["10-20", "20-30", "30-40"] 
    var Gender = ["Male", "Female"] 

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     var countrows : Int = age.count 
     if pickerView == dropdown2 { 
      countrows = self.Gender.count 
     } 

     return countrows 
    } 

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
     if pickerView == dropdown1 { 
      let titleRow = age[row] 
      return titleRow 
     } else if pickerView == dropdown2 { 
      let titleRow = Gender[row] 
      return titleRow 
     } 

     return "" 
    } 

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     if pickerView == dropdown1 { 
      self.textbox1.text = self.age[row] 
     } else if pickerView == dropdown2 {    
      self.textbox2.text = self.Gender[row] 
     } 
    } 
} 
Смежные вопросы