2016-04-28 22 views
17

Posso creare semplice viewForHeaderInSection personalizzato in modo programmatico come di seguito. Ma voglio fare cose molto più complesse, magari la connessione con una classe diversa e raggiungere le loro proprietà come una cella TableView. Semplicemente, voglio vedere quello che faccio.Swift - Come creare viewForHeaderInSection personalizzato, utilizzando un file XIB?

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 

    if(section == 0) { 

     let view = UIView() // The width will be the same as the cell, and the height should be set in tableView:heightForRowAtIndexPath: 
     let label = UILabel() 
     let button = UIButton(type: UIButtonType.System) 

     label.text="My Details" 
     button.setTitle("Test Title", forState: .Normal) 
     // button.addTarget(self, action: Selector("visibleRow:"), forControlEvents:.TouchUpInside) 

     view.addSubview(label) 
     view.addSubview(button) 

     label.translatesAutoresizingMaskIntoConstraints = false 
     button.translatesAutoresizingMaskIntoConstraints = false 

     let views = ["label": label, "button": button, "view": view] 

     let horizontallayoutContraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[label]-60-[button]-10-|", options: .AlignAllCenterY, metrics: nil, views: views) 
     view.addConstraints(horizontallayoutContraints) 

     let verticalLayoutContraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0) 
     view.addConstraint(verticalLayoutContraint) 

     return view 
    } 

    return nil 
} 


func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    return 50 
} 

C'è qualcuno da spiegare come posso creare una vista di intestazione tableView personalizzata usando xib? Mi sono imbattuto in vecchi argomenti Obj-C ma sono nuovo con il linguaggio Swift. Se qualcuno lo spiega come dettagliato, sarebbe fantastico.

1.issue: pulsante @IBAction non si collega con il mio ViewController. (fisso)

risolto con classe di base del proprietario, ViewController di File

2.issue (cliccato menù contorno sinistra.): Problema altezza Header (fisso)

Risolto aggiungendo headerView.clipsToBounds = true in viewFor HeaderInSection: metodo.

avvertimenti sui vincolithis answer solved my problems:

Quando ho aggiunto ImageView anche lo stesso vincolo altezza con questo metodo in viewController, scorrere sopra tableView righe look like picture.

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    return 120 
} 

Se uso, automaticallyAdjustsScrollViewInsets in viewDidLoad, In questo caso immagine scorre sotto navigationBar. -fixed-

self.automaticallyAdjustsScrollViewInsets = false 

3.issue: Se pulsante sotto View (fisso)

@IBAction func didTapButton(sender: AnyObject) { 
    print("tapped") 

    if let upView = sender.superview { 
     if let headerView = upView?.superview as? CustomHeader { 
      print("in section \(headerView.sectionNumber)") 
     } 

    } 
} 
+0

Prova a cercare qui: http://stackoverflow.com/questions/9219234/how-to-implement-custom-table-view-section-headers-and-footers-with-storyboard – Curmudgeonlybumbly

+0

FWIW, la risposta accettata a altra domanda è una soluzione kludgy che è stata utilizzata prima che iOS offrisse funzionalità di dequeue per le visualizzazioni di intestazione/piè di pagina. – Rob

risposta

42

Il tipico processo per le intestazioni basate NIB sarebbe:

  1. Creare UITableViewHeaderFooterView sottoclasse con almeno una presa per l'etichetta. Potresti anche dargli un identificativo con il quale puoi decodificare l'ingegnere a quale sezione corrisponde questa intestazione. Allo stesso modo, potresti voler specificare un protocollo in base al quale l'intestazione può informare il controller di visualizzazione degli eventi (come il tocco del pulsante). Quindi, in Swift 3:

    // if you want your header to be able to inform view controller of key events, create protocol 
    
    protocol CustomHeaderDelegate: class { 
        func didTapButton(in section: Int) 
    } 
    
    // define CustomHeader class with necessary `delegate`, `@IBOutlet` and `@IBAction`: 
    
    class CustomHeader: UITableViewHeaderFooterView { 
        weak var delegate: CustomHeaderDelegate? 
    
        @IBOutlet weak var customLabel: UILabel! 
    
        var sectionNumber: Int! // you don't have to do this, but it can be useful to have reference back to the section number so that when you tap on a button, you know which section you came from 
    
        @IBAction func didTapButton(_ sender: AnyObject) { 
         delegate?.didTapButton(in: sectionNumber) 
        } 
    
    } 
    
  2. Creare NIB. Personalmente, do al NIB lo stesso nome della classe base per semplificare la gestione dei miei file nel mio progetto ed evitare confusione.In ogni caso, i passi chiave includono:

    • Crea vista NIB, o se si è iniziato con un NIB vuoto, aggiungere vista al pennino;

    • Impostare la classe base della vista come qualsiasi altra sottoclasse UITableViewHeaderFooterView (nel mio esempio, CustomHeader);

    • Aggiungere i controlli e i vincoli in IB;

    • Agganciare @IBOutlet riferimenti a prese nel codice Swift;

    • Hook fino sul pulsante a @IBAction

  3. Nel viewDidLoad nel controller della vista, registrare il NIB. In Swift 3:

    override func viewDidLoad() { 
        super.viewDidLoad() 
    
        tableView.register(UINib(nibName: "CustomHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: "CustomHeader") 
    } 
    

    O a Swift 2:

    override func viewDidLoad() { 
        super.viewDidLoad() 
    
        tableView.registerNib(UINib(nibName: "CustomHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: "CustomHeader") 
    } 
    
  4. In viewForHeaderInSection, dequeue vista riutilizzabile utilizzando lo stesso identificatore specificato nel passaggio precedente. Fatto ciò, ora puoi utilizzare il tuo punto vendita, non devi fare nulla con i vincoli creati a livello di codice, ecc. L'unico pensiero che devi fare (per il protocollo per il funzionamento del pulsante) è specificare il suo delegato. Per esempio, in Swift 3:

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
        let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeader") as! CustomHeader 
    
        headerView.customLabel.text = content[section].name // set this however is appropriate for your app's model 
        headerView.sectionNumber = section 
        headerView.delegate = self 
    
        return headerView 
    } 
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
        return 44 // or whatever 
    } 
    

    O, in Swift 2:

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
        let headerView = tableView.dequeueReusableHeaderFooterViewWithIdentifier("CustomHeader") as! CustomHeader 
    
        headerView.customLabel.text = content[section].name 
        headerView.sectionNumber = section 
        headerView.delegate = self 
    
        return headerView 
    } 
    
    override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
        return 44 // or whatever 
    } 
    
  5. Ovviamente, se avete intenzione di specificare il controller della vista come delegate per il pulsante nella visualizzazione dell'intestazione , si deve conformarsi a tale protocollo:

    extension ViewController: CustomHeaderDelegate { 
        func didTapButton(in section: Int) { 
         print("\(section)") 
        } 
    } 
    

Questo tutti i suoni di confusione quando ho elencare tutte le st eps coinvolto, ma è davvero piuttosto semplice una volta che l'hai fatto una o due volte. Penso che sia più semplice della costruzione della vista dell'intestazione a livello di codice.

+0

Apprezzo la tua risposta dettagliata, ho appena iniziato a seguire i tuoi passi e approvato come risposta. Più tardi posso lasciare alcuni commenti qui come piccola domanda. Grazie di tutto. – tobeiosdev

+0

Ho aggiunto tutti i passaggi, l'intestazione sembra bene. Ma non potevo connettere il pulsante con @IBAction nel mio ViewController. Cosa mi manca, devo aggiungere un'altra cosa per il mio tableView? – tobeiosdev

+2

Il proprietario file di NIB è stato impostato come classe del controller di visualizzazione? In tal caso, quando si seleziona il pulsante, il controller di visualizzazione dovrebbe essere una delle due classi disponibili sotto l'impostazione "Automatico" nell'editor degli assistenti. – Rob

Problemi correlati