2016-06-11 5 views
0

Ich habe diese newCell Klasse:Wie kann ich andere Klasse Taste aufrufen - Swift

class newCell: UITableViewCell { 

override func awakeFromNib() { 
    super.awakeFromNib() 
    // Initialization code 
} 

override func setSelected(selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 

    // Configure the view for the selected state 
} 
@IBOutlet weak var recipeImage: UIImageView! 

@IBOutlet weak var recipeTitle: UILabel! 

@IBOutlet weak var favoriteButton: UIButton! 

@IBAction func favoriteAction(sender: AnyObject) { 


} 

Im HomeViewController, verwende ich diese newCell Klasse als Prototyp Zelle für meine Tabellenansicht. Es funktioniert gut für Texte und Bilder. Mein Zweifel ist, wie kann ich einen Knopf dieser Prototypzelle in meinem HomeViewController handhaben? Zum Beispiel möchte ich, dass die Schaltfläche das Bild entsprechend dem übergebenen Array ändert.

override func viewDidLoad() { 
    super.viewDidLoad() 

    var recipesFeed = PFQuery(className: "Recipe") 

    recipesFeed.findObjectsInBackgroundWithBlock { (objects, error) -> Void in 

     if let recipes = objects { 

     self.recipes.removeAll(keepCapacity: true) 
     self.recipeImages.removeAll(keepCapacity: true) 
     self.isFavorite.removeAll(keepCapacity: true) 


      for recipe in recipes{ 

       self.recipes.append(recipe["title"] as! String) 
       self.recipeImages.append(recipe["image"] as! String) 
       self.isFavorite.append(recipe["isFavorite"] as! Int) 

       self.tableView.reloadData() 

      } 

     } 

    } 

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let myCell = self.tableView.dequeueReusableCellWithIdentifier("prototypeCell") as! newCell 

images[indexPath.row].getDataInBackgroundWithBlock { (image, error) -> Void in 

     if let downloadedImage = UIImage(data: image!){ 

      myCell.recipeImage.image = downloadedImage 

     } else { 

      myCell.recipeImage.image = UIImage(named: "background_recipe_image.png") 
     } 


    } 

    myCell.recipeTitle.text = recipes[indexPath.row] 
    //begin what I try and doesn't work 
    myCell.favoriteAction(sender: AnyObject) { 

    if isFavorite[indexPath.row] == 1 { 
     if let image = UIImage(named: "star vector.png") { 

     myCell.favoriteButton.setImage(image, forState: .Normal) 


    } 

    } else { 

    if let image = UIImage(named: "star vector blank.png") { 

     myCell.favoriteButton.setImage(image, forState: .Normal) 

    } 
    } 
    } 
    //end what I try and doesn't work 
    return myCell 
} 
+0

Dieser Code macht keinen Sinn: 'myCell.favoriteAction (Absender: AnyObject) {' Die Deklaration für 'favoriteAction' ist bereits in der' newCell' Klasse. Das ist, wo der Code für das geht, was geschehen soll, wenn der Benutzer auf die Schaltfläche Favoriten klickt. – matt

+0

Ok, tut mir leid, das ist ziemlich neu für mich. Wie kann der Code in newCell das Bild dieser Schaltfläche entsprechend einem Array von HomeViewController ändern? Ist das möglich? Danke im Voraus. –

+0

Können Sie den Code für den HomeViewController posten? (oder zumindest einen Teil davon). @ RafaelDontalGonçalez – Ike10

Antwort

1

Also meine Methode für den Zugriff auf die isFavorited Array in der HomeViewController ist ein Delegierungsmuster mit zwei Protokollen zu verwenden.

protocol hasFavBtn { 

    var delegate: FavBtnDelegate! { get set } 
    var delegateTableView: UITableView! { get set } 

} 

protocol FavBtnDelegate { 

    var isFavorited: [Int] { get set } 

} 

hierfür Um das hasFavBtn Protokoll arbeiten sollte die NewCell Klasse entspricht und die HomeViewController zum FavBtnDelegate Protokoll entsprechen sollten. Wie so:

HomeViewController

class ViewController: UITableViewController, FavBtnDelegate { 

    var isFavorited = [0, 0, 0, 0, 1] 

    let newCellStr = "NewCell" 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let newCell = tableView.dequeueReusableCellWithIdentifier(newCellStr) as! NewCell 

    newCell.delegate = self 
    newCell.delegateTableView = tableView 

    return newCell 
    } 
} 

Die wichtige Sache hier zu bemerken sind:

  1. In cellForRowAtIndexPath die delegate und delegateTableView Eigenschaften für die Instanz der NewCell Klasse definiert werden, bevor der newCell konstant ist zurück gekommen.

  2. Die Variable isFavorited wird wie im Protokoll FavBtnDelegate beschrieben eingestellt.

NewCell.swift

class NewCell: UITableViewCell, hasFavBtn { 

    var delegate: FavBtnDelegate! 
    var delegateTableView: UITableView! 

    @IBOutlet weak var favoriteBtn: UIButton! 

    let blankStarImg = UIImage(imageLiteral: "blankStar") 
    let fullStarImg = UIImage(imageLiteral: "fullStar") 

    override func awakeFromNib() { 
    super.awakeFromNib() 
    let blankStarImg = UIImage(imageLiteral: "blankStar") 
    favoriteBtn.setBackgroundImage(blankStarImg, forState: .Normal) 
    } 

    @IBAction func favoriteBtnPressed(sender: AnyObject) { 
    let locationInCell = CGPoint(x: (sender.frame.maxX - sender.frame.minX)/2, y: (sender.frame.maxY - sender.frame.minY)/2) 
    let locationInDelegateTableView = convertPoint(locationInCell, toView: delegateTableView) 

    if let indexPath = delegateTableView.indexPathForRowAtPoint(locationInDelegateTableView) { 
     if delegate.isFavorited[indexPath.row] == 1 { 
     favoriteBtn.setBackgroundImage(fullStarImg, forState: .Normal) 
     } 
    } 
    } 

Wie andere gesagt haben, es ist hier, dass die UITableViewCell Unterklasse, dass Sie die @IBAction für die Favoriten-Taste definieren sollen. Sie können über die Eigenschaft delegate auf das Array TableView und das Array isFavorited verweisen, da in cellForRowAtIndexPath der Wert für die Eigenschaft delegateTableView auf die TableView des HomeViewControllers gesetzt wurde und die Eigenschaft delegate auf die HomeViewController-Instanz gesetzt wurde (mit dem Schlüsselwort self).

So favoriteBtnPressed Funktion ermittelt den Mittelpunkt (CGPoint) der Taste, die gedrückt wurde, und wandelt dann die auf das Koordinatensystem des delegateTableView und dadurch die in der HomeViewController tableview.Mit der konvertierten Mitte der Schaltfläche im Koordinatensystem der TabelleView verwendet der Code eine if let-Bindung, um die indexPath für das konvertierte Zentrum sicher auszupacken. Dann können Sie mit der unverpackten indexPath und der delegate Eigenschaft überprüfen, ob der Array-Wert des HomeViewControllers isFavorited an der gegebenen indexPath gleich 1 ist und das Bild entsprechend anpassen.

Die Protokolle und Delegationsmuster des Swift sind sehr leistungsfähig und nützlich für viele Dinge. Sie können mehr über sie hier lesen: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

Beachten Sie auch, dass ich meine Bilder in der Assets.xcassets-Datei, so dass ich den ImageLiteral-Initialisierer verwendet, um sie zu bekommen.

Hoffe, das hilft! Wenn Sie Fragen haben, zögern Sie nicht zu fragen!

+0

Tausend Dank für deinen Code und arbeite daran @ Ike10. Ich versuche deinen Ansatz und komme mit dem Feedback zurück. = D –

+0

Das war großartig. Ich hatte dieses Konzept nicht über Protokoll und delegiere. Ich habe es jetzt, dank dir. Der Code funktioniert teilweise, aber ich habe HomeVC Array in newCell favoriteButtonPressed verwendet. In Zukunft werde ich mehr Fragen dazu stellen, aber für den Moment werde ich einige Zeit damit verbringen, zu lernen und selbst zu bestimmen. Danke noch einmal. –

1

Sie haben eine Aktion favoriteAction in Ihrem tableviewcell bereits. Die einfache Lösung für Ihr Problem ist übergeben Sie das Array der möglichen Bilder in die Tabelle viewcell, wenn es aus der Warteschlange und dann Sie den Code, der die Bilder in der favoriteAction IBAction austauscht.

Wenn Sie nicht herausfinden können, was ich von meiner Beschreibung oben tun soll, kann ich etwas Code posten, aber versuchen Sie es zuerst herauszufinden. Ich denke, es ist eine gute Lernübung.

+0

Danke für deine Antwort, Daniel. Ja, ich konnte und ich tat es in der Klasse newCell, aber wie kann ich feststellen, dass die Taste in der HomeVC gedrückt wurde, so dass ich mit den Arrays arbeiten kann, die aus der Datenbank abgefragt wurden? Tut mir leid, wenn ich nicht klar bin, es könnte schwierig sein, es einmal zu erklären, und danke nochmal. –

+0

Sie müssen nicht feststellen, dass die Taste im HomeVC gedrückt wurde. Stattdessen müssen Sie es so einrichten, dass die Tabellenansichtszelle mit den aus der Datenbank abgefragten Arrays arbeiten kann. Lies meine Antwort noch einmal, ich habe den wichtigsten Teil fett markiert. –

+1

Blick auf Ihren Code ... Sie sollten nicht drei separate Arrays haben. Sie müssen ein 'struct Rezept {var title: String; var imageName: Zeichenfolge; var isFavorite: Int} '. Anschließend können Sie das entsprechende Rezeptobjekt an die Tabellenansichtszelle übergeben, damit es sich anhand der Informationen in der Struktur selbst konfigurieren kann. –

Verwandte Themen