2016-01-06 4 views
1

У меня есть 3 пользовательских ячейки, которые находятся в подклассе из viewController Uitableview, в котором они находятся. В ячейках есть распознаватель жестов, чтобы увидеть, где они были затронуты, чтобы изменить значки/фоны, тогда результат будет сохранен для основных данных. Я хочу, чтобы ситуация была сохранена, и ячейки сбрасываются на базовые цвета и графику, когда какая-либо ячейка не трогается в течение 3 секунд (чтобы удалить кнопку сохранения). У меня все сделано нормально, но я не могу сделать какой-либо метод для их сброса в одно и то же время. Я пробовал так много разных способов, и я думал, что лучший способ - перезагрузить таблицу в диспетчере представлений, но я не смог заставить ее работать. На данный момент я использую Struct с дубинкой. Когда касание заканчивается на любой ячейке, он вызывает таймер, и если он заканчивается без другого касания, он вызывает метод сохранения и сброса. Возможно, это неправильный способ сделать это, чтобы я немного застрял.Swift: одновременно перезагрузка нескольких подклассовых пользовательских uitableviewcells?

storyboard

класс Посмотреть контроллер

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
return 1 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->  
Int { 
return measurements.count 

} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

if indexPath.row == 0 { 

    let cell = tableView.dequeueReusableCellWithIdentifier("BmCustomCell", forIndexPath: indexPath) as! BmTableViewCell 


    return cell 

} else if indexPath.row == 1 { 


    let cell = tableView.dequeueReusableCellWithIdentifier("StressCustomCell", forIndexPath: indexPath)as! StressTableViewCell 


    return cell 
} else { 


    let cell = tableView.dequeueReusableCellWithIdentifier("PainCustomCell", forIndexPath: indexPath) as! PainTableViewCell 

    return cell 
     } 
} 

Пример класса painTableViewCell (такой же, как другие два)

// if touched the text changes and the icon changes. if not touched for 5 seconds resets to not touched. 

func resetTouchedPainAfterFiveSecs(){ 

if TouchNotification.isBeingTouched == false { 
    timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("reset"), userInfo: nil, repeats: false) 
} else { 
    timer.invalidate() 
} 
} 

func reset(){ 

ResetTables().resetAllTables() 
savePainData() 
} 


// reset pain ui to ready to go state 
func resetPain() { 
TouchNotification.reset = true 

if TouchNotification.reset == true { 
    painLabel.textColor = whiteColour 
    painIcon.image = UIImage(named: "IconPain 0 Unused") 
    touchedPain = false 
    painLabel.text = "Pain" 
    TouchNotification.reset = false 

} 
} 

TouchNotification

struct TouchNotification { 
static var isBeingTouched = false 
static var reset = false 
} 

Сброс класса

class ResetTables: UIViewController { 

func resetAllTables(){ 

StressTableViewCell().resetStress() 
BmTableViewCell().resetBM() 
PainTableViewCell().resetPain() 

} 

} 

ответ

1

Вы говорите: «Я думал, что лучший способ - перезагрузить таблицу в контроллере представления, но я не смог заставить ее работать». Да, это именно то, что я вам предлагаю (хотя я мог бы предложить reloadRowsAtIndexPaths).

А гораздо более тонкая проблема заключается в том, что, особенно по мере того, как ваш пользовательский интерфейс становится более сложным, ячейки могут прокручиваться с экрана, могут быть повторно использованы и т. Д. В результате вы обычно хотите избегать непосредственного обновления ячеек. Что делать, если одна или несколько из этих ячеек прокручиваются с экрана к моменту их сброса? Как, когда он прокрутится назад, вы узнаете, что делать с этой ячейкой? И т.д.

Из-за этого вы часто хотите отделить UI (ячейки) от модели (информация о том, какие ячейки представляют собой цвет).Как только вы это сделаете, вы можете перейти в мир, в котором у вас есть структура модели (в моем примере ниже, cellBackgroundColors), который отслеживает, какой цвет должен быть ячейкой. Затем cellForRowAtIndexPath установит цвет ячейки на основе этого модельного объекта. Затем, когда вы хотите изменить цвет ячейки, вы (а) обновите этот объект модели, а затем (b) сообщите, что представление таблицы перезагружает эту ячейку.

Если вы хотите обновить несколько ячеек одновременно, вы затем обновите свою модель и вызовите reloadRowsAtIndexPaths с помощью массива ячеек, а затем все они будут обновлены одновременно. Но вы также будете делать это безопасным образом, что не зависит от того, какие ячейки на экране в то время. И если я правильно сформулирую, что вы хотите, чтобы таймер перезапустился, если они нажмут на что-то еще, вы можете установить таймер и создать новый каждый раз, когда пользователь нажимает на ячейку.

Вот маленький пример:

class ViewController: UITableViewController { 

    var cellBackgroundColors: [UIColor]! 
    let defaultColor = UIColor.whiteColor() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     resetCellBackgroundColorsToDefault() 
    } 

    func resetCellBackgroundColorsToDefault() { 
     cellBackgroundColors = [UIColor.redColor(), UIColor.yellowColor(), UIColor.cyanColor()] 
    } 

    // MARK: UITableViewDataSource 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 100 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 

     // do whatever cell configuration you want here 

     // but programmatically set the background color (or whatever) based upon the model: 

     if indexPath.row < 3 { 
      cell.backgroundColor = cellBackgroundColors[indexPath.row] 
     } else { 
      cell.backgroundColor = defaultColor 
     } 

     return cell 
    } 

    // MARK: UITableViewDelegate 

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     tableView.deselectRowAtIndexPath(indexPath, animated: false) 

     cellBackgroundColors[indexPath.row] = UIColor.blueColor() 

     tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 

     timer?.invalidate() 
     timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "resetCells:", userInfo: nil, repeats: false) 
    } 

    // MARK: Timer code 

    weak var timer: NSTimer? 

    func resetCells(timer: NSTimer) { 
     resetCellBackgroundColorsToDefault() 

     let indexPaths = [0, 1, 2].map { NSIndexPath(forRow: $0, inSection: 0) } 

     tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: .Fade) 
    } 

} 
+0

Ячейки меняют цвет и значок, основываясь на том, где вы их касаетесь. Чем больше справа, тем выше результат. Могу ли я сохранить этот расчет в пользовательских классах ячеек? – SashaZ

+0

Вам необходимо обновить модель. Вы можете либо настроить некоторый делегат-протокол для ячейки, чтобы информировать контроллер вида, чтобы он мог соответствующим образом обновить модель, либо подключить жест жестки/розетки напрямую к контроллеру представления. Вы можете непосредственно обновить свой цвет ячеек (и отказаться от 'updateCellsAtIndexPaths', который я сделал в' didSelectRowAtIndexPath'), но вы все же хотите обновить модель в случае прокрутки ячейки, а затем назад, запуская «cellForRowAtIndexPath» снова называется. – Rob

+0

Спасибо, завтра. – SashaZ

2

Похоже, проблема в том, что вы создаете новые экземпляры объектов вместо того, чтобы использовать те, на экране.

Возьмем, к примеру,

ResetTables().resetAllTables()

который называет

func resetAllTables(){ 
    StressTableViewCell().resetStress() 
    BmTableViewCell().resetBM() 
    PainTableViewCell().resetPain() 
} 

Что вы делаете с ResetTables() создает новый объект класса ResetTables, а затем вызвать resetAllTables() на нем, который, в свою очередь, создает новую ячейку, StressTableViewCell и вызывает на ней resetStress. То же самое касается двух других ячеек. Хотя вы :, вызывающие методы, вы не вызываете их на отображаемые ячейки, а на новые ячейки, которые после того, как функция покидает область действия, освобождаются.

Итак, в вашем методе reset() вы хотите сбросить самую ячейку, а не создавать новые ячейки, которые вы сбросили.

+0

Да, это то, что я думал, что из сообщений об ошибках, которые я получаю. – SashaZ

Смежные вопросы