这是一个两部分的问题,第一个问题是经过一整周的尝试来解决这个问题后,我仍然留空。我最终让单个单元格显示与文本字段中的选择相关的适当数字,但仍然没有弄清楚为什么重新加载到tableview中的单元格也显示更新的文本字段。基本上我只想让cardCounter的文本字段仅在选定的行中更新然后如果用户滚动回到那里,如果他们决定删除它,它会向他们显示该对象有多少可用的计数器。
第二个问题是我正在尝试为总数限制为30的cardCount制作一个计数器,并且对于每个选择的cardCount对象,其中有30个选项中的一个已经缩小到29,28,27等等。在我的第一个项目中完成一些次要代码。
import UIKit
import CoreData
class CardSelectionViewController: UIViewController, UITableViewDelegate, UIAlertViewDelegate, UISearchBarDelegate, NSFetchedResultsControllerDelegate {
var passedDeckObject: Deck?
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var deckCardCount = 30
@IBOutlet weak var cardsListed: UITableView!
@IBOutlet weak var cardSearch: UISearchBar!
@IBAction func backButton(sender: AnyObject) {
}
@IBAction func saveCardSelection(sender: AnyObject) {
if deckCardCount != 30 {
let selectmorecards = UIAlertController(title: "Select More Cards", message: "Please Select More Cards To Complete Deck", preferredStyle: .Alert)
let okCardAction: UIAlertAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
selectmorecards.addAction(okCardAction)
self.presentViewController(selectmorecards, animated: true, completion: nil)
} else {
if deckCardCount == 30 {
let alertController = UIAlertController(title: "All Cards Correct?", message: "Are all the cards in the deck what you wanted?", preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
let okAction: UIAlertAction = UIAlertAction(title: "OK", style: .Default) { (action) -> Void in
self.managedObjectContext?.save(nil)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
}
var costfrc: NSFetchedResultsController!
var frc: NSFetchedResultsController = NSFetchedResultsController()
func getFetchedResultsController() -> NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: listFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
return frc
}
func listFetchRequest() -> NSFetchRequest {
let requiredClassName = passedDeckObject!.classSelected.classname
var requiredCardClasses = [Int]()
let fetchRequest = NSFetchRequest(entityName: "Cards")
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
switch(requiredClassName) {
case "Warrior":
requiredCardClasses = [1,10]
case "Shaman":
requiredCardClasses = [2,10]
case "Rogue":
requiredCardClasses = [3,10]
case "Paladin":
requiredCardClasses = [4,10]
case "Hunter":
requiredCardClasses = [5,10]
case "Druid":
requiredCardClasses = [6,10]
case "Warlock":
requiredCardClasses = [7,10]
case "Mage":
requiredCardClasses = [8,10]
case "Priest":
requiredCardClasses = [9,10]
default:
requiredCardClasses = [10]
}
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format:"cardClass IN %@", requiredCardClasses)
return fetchRequest
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let numberofRowsInSection = frc.sections?[section].numberOfObjects
return numberofRowsInSection!
}
//Mark cell displayed with colored text//
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: firstCardDetails = cardsListed.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! firstCardDetails
let listed = frc.objectAtIndexPath(indexPath) as! Cards
var cardCount = 0
var myDeckCards: DeckCards?
for eachDeckCard in listed.cardselections {
let myDeckCard = eachDeckCard as! DeckCards
if myDeckCard.cardsstored == passedDeckObject {
myDeckCards = eachDeckCard as? DeckCards
cardCount = myDeckCards!.numberSelected.integerValue
}
}
cell.cardName?.text = listed.name as String
if listed.cardType.isEqualToValue(1) {
cell.cardAttack?.text = "*"
} else {
if listed.cardType.isEqualToValue(2) {
cell.cardAttack?.text = "*"
} else {
cell.cardAttack?.text = listed.attack.stringValue
}
}
if listed.cardType.isEqualToNumber(1) {
cell.cardHealth?.text = "*"
} else {
if listed.cardType.isEqualToValue(2) {
cell.cardHealth?.text = "*"
} else {
cell.cardHealth?.text = listed.health.stringValue
}
}
cell.cardCost?.text = listed.cost.stringValue
if listed.cardType.isEqualToNumber(0) {
cell.cardType?.text = "Minion"
} else {
if listed.cardType.isEqualToNumber(1) {
cell.cardType?.text = "Spell"
} else {
if listed.cardType.isEqualToNumber(2) {
cell.cardType?.text = "Weapon"
}
}
}
if listed.rarity.isEqualToNumber(1) {
cell.rarityType?.text = "Legendary"
cell.rarityType?.textColor = UIColor.orangeColor()
} else {
if listed.rarity.isEqualToNumber(2) {
cell.rarityType?.text = "Epic"
cell.rarityType?.textColor = UIColor.purpleColor()
} else {
if listed.rarity.isEqualToNumber(3) {
cell.rarityType?.text = "Rare"
cell.rarityType?.textColor = UIColor.blueColor()
} else {
if listed.rarity.isEqualToNumber(4) {
cell.rarityType?.text = "Common"
cell.rarityType?.textColor = UIColor.grayColor()
} else {
if listed.rarity.isEqualToNumber(5) {
cell.rarityType?.text = "Starter"
cell.rarityType?.textColor = UIColor.blackColor()
}
}
}
}
}
if listed.cardClass.isEqualToNumber(1) {
cell.cardName?.textColor = UIColor(red: 0xbe/255, green: 0x23/255, blue: 0x0f/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(2) {
cell.cardName?.textColor = UIColor.blueColor()
} else {
if listed.cardClass.isEqualToNumber(3) {
cell.cardName?.textColor = UIColor(red: 0xE2/255, green: 0xA8/255, blue: 0x79/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(4) {
cell.cardName?.textColor = UIColor(red: 0xFF/255, green: 0xAA/255, blue: 0x00/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(5) {
cell.cardName?.textColor = UIColor(red: 0x22/255, green: 0x63/255, blue: 0x29/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(6) {
cell.cardName?.textColor = UIColor.brownColor()
} else {
if listed.cardClass.isEqualToNumber(7) {
cell.cardName?.textColor = UIColor(red: 0xBB/255, green: 0x76/255, blue: 0xE4/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(8) {
cell.cardName?.textColor = UIColor(red: 0x9E/255, green: 0xB5/255, blue: 0xFF/255, alpha: 1.0)
} else {
if listed.cardClass.isEqualToNumber(9) {
cell.cardName?.textColor = UIColor.grayColor()
} else {
if listed.cardClass.isEqualToNumber(10) {
cell.cardName?.textColor = UIColor.blackColor()
}
}
}
}
}
}
}
}
}
}
return cell
}
//reload content//
func controllerDidChangeContent(controller: NSFetchedResultsController) {
cardsListed.reloadData()
}
//selected row functions//
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cardCount = 0
var myDeckCards: DeckCards?
let listed = frc.objectAtIndexPath(indexPath) as! Cards
var cell = cardsListed.cellForRowAtIndexPath(indexPath) as! firstCardDetails
cell.indexOfAccessibilityElement(listed)
// check: is there already a DeckCards object for this Card and this Deck?
let deckCardsSet = listed.cardselections
println("The set of DeckCards for that Card is \(deckCardsSet.count)")
for eachDeckCard in listed.cardselections {
let myDeckCard = eachDeckCard as! DeckCards
if myDeckCard.cardsstored == passedDeckObject {
// There is already a DeckCard object for this Card and currentDeck
myDeckCards = eachDeckCard as? DeckCards
}
}
if myDeckCards == nil {
// There is no DeckCard object for this Card and currentDeck
// So create one...
myDeckCards = NSEntityDescription.insertNewObjectForEntityForName("DeckCards", inManagedObjectContext: managedObjectContext!) as? DeckCards
myDeckCards!.cardsselected = listed
myDeckCards!.cardsstored = passedDeckObject!
}
// your code to determine numberSelected here; I'll assume 2!
cardCount = myDeckCards!.numberSelected.integerValue
deckCardCount = myDeckCards!.deckcardCount.integerValue
cardCount = cardCount == 2 ? 0 : cardCount + 1
myDeckCards!.numberSelected = cardCount
deckCardCount = deckCardCount - cardCount
cell.cardCounter.text = " " + cardCount.description
if deckCardCount == 30 {
if cell.selected {
deckCardCount = deckCardCount + 1
}
myDeckCards!.numberSelected = deckCardCount
myDeckCards!.numberSelected = cardCount
}
println(deckCardCount)
println(cardCount)
}
//searchBar contoller//
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.setShowsCancelButton(true, animated: true)
let requiredClassName = passedDeckObject!.classSelected.classname
var requiredCardClasses = [Int]()
switch(requiredClassName) {
case "Warrior":
requiredCardClasses = [1,10]
case "Shaman":
requiredCardClasses = [2,10]
case "Rogue":
requiredCardClasses = [3,10]
case "Paladin":
requiredCardClasses = [4,10]
case "Hunter":
requiredCardClasses = [5,10]
case "Druid":
requiredCardClasses = [6,10]
case "Warlock":
requiredCardClasses = [7,10]
case "Mage":
requiredCardClasses = [8,10]
case "Priest":
requiredCardClasses = [9,10]
default:
requiredCardClasses = [10]
}
if !searchText.isEmpty {
// Clear out the fetchedResultController
frc = getFetchedResultsController()
// Setup the fetch request
let fetchRequest = NSFetchRequest(entityName: "Cards")
fetchRequest.fetchLimit = 565
fetchRequest.predicate = NSCompoundPredicate(type: .AndPredicateType, subpredicates: [NSPredicate(format: "name contains[cd] %@", searchText), NSPredicate(format: "cardClass IN %@", requiredCardClasses)])
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
println(fetchRequest.predicate)
//end//
//cost fetch request begins here//
let costfetchRequest = NSFetchRequest(entityName: "cardCost")
costfetchRequest.fetchLimit = 565
costfetchRequest.predicate = NSPredicate(format: "cardCost = %i", searchText)
let costSortDescriptor = NSSortDescriptor(key: "cardCost", ascending: true)
costfetchRequest.sortDescriptors = [sortDescriptor]
//end//
// Pass the fetchRequest and the context as parameters to the fetchedResultController
frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext:managedObjectContext!,
sectionNameKeyPath: nil, cacheName: nil)
// Make the fetchedResultController a delegate of the MoviesViewController class
frc.delegate = self
// Execute the fetch request or display an error message in the Debugger console
var error: NSError? = nil
if (!frc.performFetch(&error)) {
println("Error: \(error?.localizedDescription)")
}
// Refresh the table view to show search results
cardsListed.reloadData()
}
}
//search Cancel
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBar.text = nil
searchBar.showsCancelButton = false // Hide the cancel
searchBar.resignFirstResponder() // Hide the keyboard
// Refresh the table view to show fetchedResultController results
cardsListed.reloadData()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func viewDidLoad() {
super.viewDidLoad()
println(passedDeckObject?.deckname)
var nib = UINib(nibName: "firstCardDetails", bundle: nil)
cardsListed.registerNib(nib, forCellReuseIdentifier: "cell")
frc = getFetchedResultsController()
frc.delegate = self
frc.performFetch(nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
答案 0 :(得分:0)
对于问题#1 ....
当您使用可重复使用的单元格时,在cellForRowAtIndexPath
(或prepareForReuse
)之外进行单元格更改通常是个坏主意。有例外,但大多数时候,这是安全的赌注。最好的策略是在其他方法中使数据更改 ,然后重新加载受影响的单元格(或所有方法)。
由于单元格被缓存,因此只要使用该单元格,您对单元格所做的更改就会显示在屏幕上,除非您在返回单元格时明确覆盖更改。
您应该在didSelectRowAtIndexPath
方法中计算出您需要的内容并将其存储在某个位置,然后在cellForRowAtIndexPath
中更新它的显示。