2016-12-29 10 views
-1

これは必ずしも必要なことではありません。可能であればそれはいいだろう。これができるかどうかはわかりません。UIPickerViewでセクションタイトルを追加するにはどうすればよいですか?

私にはUIPickerViewがあり、41-42個のオプションがあります。今はすべてのオプションをアルファベット順に並べています。私はそれらをグループに分けて、各グループの前にタイトルを付けたいと思っています。 TableViewにセクションがある方法と同様に、各セクションにタイトルを付けることができます。ピッカーの各セクションのタイトルが必要ですが、選択可能な行にしたくありません。

ピッカーオプション:例えば
コア(selecteableない)
バーバリアン(選択)
バード(選択)(選択しない)
いくつかのより多くのオプション
APG
錬金術(選択)
キャバリエ(選択可能)
複数のオプション
続きを見る

これも可能ですか?

+0

あなたは – Starlord

+0

あなたは少し手の込んだてもらえことを行うことができますか? Duncan Cが示唆したものとは別の方法がありますか?チュートリアルへのリンクはありますか? – Micheal

+0

ホールドオン...いくつかの簡単なサンプルコードを作成 – Starlord

答えて

-1

いいえ、私は標準のピッカービューではそのオプションを提供していないと思います。つまり、UIPickerViewをサブクラス化し、カスタムサブクラスに記述したようにセクションディバイダを持つように教えることができます。

あなたが記述しているようにセクションを持つピッカーのように機能する独自のコントロールを作成することは、確かに可能です。

+0

ありがとうございました。今、私は物事を複雑にすることを考えていません。私のアプリを簡単に保つことを試みている。私はXcodeを学んでいます。私は言語の理解を深めるまでこれをバックバーナーに置くことができます。それはもっと贅沢なことであり、必要ならば贅沢です。 – Micheal

+0

'UIPickerViewDelegate'の' pickerView(_:viewForRow:forComponent:reusing:) 'は、グループ指定子と選択可能な項目の異なるビューを返すために呼び出すことができます。サブクラス化は必要ありません。 – vikingosegundo

+0

これをさらに詳しく見ていきます。 Appleのマニュアルを読んで、チュートリアルを探します。私はどこから始めるべきかわからなかった。これは良い出発点です。有難うございます。 – Micheal

0

編集:@Duncan Cは彼の答えに言及しています。このためのソリューションはiOS7 +に組み込まれていません。私の答えはあなたの目標を達成する別の方法を提供します。

iOS 7以前では、showsSelectionIndicatorを使用すると、選択した状態をピッカービューのさまざまなオブジェクトに表示できませんでした。しかし、iOS7 +ではこれが許可されていません。

iOS 7以降では、ピッカービューの選択インジケータをカスタマイズすることはできません。選択インジケータが常に表示されるため、このプロパティをfalseに設定しても効果はありません。

代わりにあなたは少し厄介なハック行うことができます。

をデリゲートはUIPickerViewDelegateプロトコルを採用し、いずれかの属性付き文字列、プレーンな文字列、またはビューとして、各コンポーネントの行のためのコンテンツを提供し、通常は新しい選択や選択解除に応答します。

この簡単な例では、ソリューションがどのように機能するかを示しています。これらをに選択できないピッカーオブジェクトにするには、とは異なる文書に記載されているように属性付き文字列を使用できます。

ヘッダオブジェクトのいずれかを選択しようとすると、ピッカービューを閉じないでください。ユーザーは別のオプションを選択する必要があり、時間の経過とともに、太字の文字列でこれらのオブジェクトを選択できないことがわかります。

var datasource = ["Core", "content", "content", "content", "APG", "content", "content"] 


func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 
print(self.datasource[row]) 
switch row { 
    case 0: 
     // create attributed string 
     let myString = datasource[row] 
     let myAttribute: [String:Any] = [ NSForegroundColorAttributeName: UIColor.blue, NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue ] 
     let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 

     return myAttrString 
    case 15: 
     let myString = datasource[row] 
     let myAttribute: [String:Any] = [ 
    NSForegroundColorAttributeName: UIColor.blue, 
    NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue ] 
     let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 

     return myAttrString 

    case 4: 
     let myString = datasource[row] 
     let myAttribute: [String:Any] = [ 
    NSForegroundColorAttributeName: UIColor.blue, 
    NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue ] 
     let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 
     return myAttrString 
    default: 
     //It all depends on your datasource, but if you have 0-42 strings(core, APG included) you can just output the rest under default here 
     let myString = datasource[row] 
     let myAttribute: [String:Any] = [ NSForegroundColorAttributeName: UIColor.black] 
     let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 
     return myAttrString 

     } 

} 

これはうまく見えませんが、あなたが望むようにカスタマイズすることができます。ピッカービューオブジェクトに画像またはUiViewを追加することもできます。

UIPickerView example

+1

これを改善するために、ユーザーがセクションタイトルのある行を選択すると、その選択が自動的に次の行に更新されます。 – rmaddy

1

あなたは、むしろ思慮深く、データソースとデリゲートを実装し、これを達成するためにUIPickerViewをサブクラス化する必要はありません。あなたはこのクラスはコールバックvar selected: (([String: Any]) -> Void)?を持って見たよう

import UIKit 

class PickerViewSource: NSObject, UIPickerViewDelegate, UIPickerViewDataSource { 

    init(pickerView: UIPickerView) { 
     super.init() 
     pickerView.dataSource = self 
     pickerView.delegate = self 
    } 

    var selected: (([String: Any]) -> Void)? 

    let data = [ 
     ["title": "Group a", "selectable": false], 
     ["title": "title a1", "selectable": true], 
     ["title": "title a2", "selectable": true], 
     ["title": "title a3", "selectable": true], 
     ["title": "Group b", "selectable": false], 
     ["title": "title b1", "selectable": true], 
     ["title": "title b2", "selectable": true], 
     ["title": "Group c", "selectable": false], 
     ["title": "title c1", "selectable": true], 
     ["title": "title c2", "selectable": true], 
     ] 

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

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

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { 

     let d = data[row] 
     if let selectable = d["selectable"] as? Bool, selectable == true { 

      if let view = view as? ItemView, let title = d["title"] as? String{ 
       view.label.text = title 
       return view 
      } 
      let view = ItemView() 
      if let title = d["title"] as? String{ 
       view.label.text = title      
      } 
      return view 
     } 

     if let selectable = d["selectable"] as? Bool, selectable == false { 
      if let view = view as? GroupView, let title = d["title"] as? String{ 
       view.label.text = title 
       return view 
      } 
      let view = GroupView() 
      if let title = d["title"] as? String{ 
       view.label.text = title      
      } 
      return view 

     } 
     return UIView() 
    } 

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     var index = row 
     if let selectable = data[row]["selectable"] as? Bool, selectable == false { 
      index += 1 
      pickerView.selectRow(index, inComponent: 0, animated: true) 
     } 
     selected?(data[index]) 
    } 

} 

は、私はこのようなやったテストとして、あなたは両方を実装するクラスを持つことをお勧めします。選択可能なアイテムについてのみ呼び出されます。

のViewControllerは、ソースをインスタンス化し、コールバック設定:

class ViewController: UIViewController { 

    var pickerViewSource: PickerViewSource? 

    @IBOutlet weak var pickerView: UIPickerView! { 
     didSet{ 
      pickerViewSource = PickerViewSource(pickerView: pickerView) 

      pickerViewSource?.selected = { 
       selected in 

       print(selected) 
      } 
     } 
    } 
} 

とcompletnessために、ビュー:

class BaseView: UIView { 
    var label: UILabel = UILabel() 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     self.addSubview(label) 
     label.frame = self.bounds 
    } 
} 

class GroupView: BaseView { 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     label.backgroundColor = .orange 
    } 

} 

class ItemView: BaseView { 

} 

screen


の代わりに選択することによって、選択を強制します次の行、あなたはグループを選択することができますが、d選択コールバックを送信しません。しかし、選択可能なものが何も設定されていないことを確実にするには、選択解除コールバックを追加する必要があります。

var selectedElement: [String:Any]? 

var deselected: (([String: Any]) -> Void)? 

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

    if let element = selectedElement { 
     deselected?(element) 
     selectedElement = nil 
    } 

    if let selectable = data[row]["selectable"] as? Bool, selectable == true { 
     let element = data[row] 
     selected?(element) 
     selectedElement = element 
    } 

} 

今、あなたは、エンまたは無効にボタンをすなわちし、ユーザーインターフェイスを変更するコールバックselecteddeselectedを使用することができます。完全例えば

は、私はちょうど発表され、このサンプルコードを参照してください。https://github.com/vikingosegundo/PickerWithSectionTitlesExample

関連する問題