Цвет фона изменяется для нескольких ячеек таблицы, если в таблице более 7 строк - PullRequest
0 голосов
/ 29 января 2019

Я читаю данные из Firebase и затем отображаю эти данные в ячейках табличного представления.Существует также файл, хранящийся локально, который содержит статус чтения / непрочитанного для каждой ячейки.Файл содержит ключ каждого дочернего элемента в Firebase, и я сопоставляю его с данными в каждой ячейке.

Обычно, если в ячейке есть ключ, который также находится в файле, эти данные считаются пользователем «прочитанными».Однако, если в ячейке есть ключ, который не имеет эквивалента в локальном файле, эти данные считаются «непрочитанными».

Пока это работает отлично.Затем я добавил две функции смахивания для каждой ячейки.Сначала пометить как прочитанное, а также пометить как непрочитанное.При пометке «прочитано», свайп вызывает функцию, которая записывает ключ для ячейки в локальный файл.И наоборот, при пометке «непрочитанные» свайп вызывает другую функцию, которая удаляет ключ из локального файла.Это также прекрасно работает.

Однако при пролистывании мне также нужно изменить цвет фона ячейки, чтобы он отображал «прочитанный» или «непрочитанный».Это вызывает проблему, потому что ячейки перезагружаются для повторного использования ... в моем случае, я получаю 7 ячеек до перезагрузки.

Это означает, что если у меня более 7 ячеек и я помечаю что-то как «прочитанное», я в конечном итоге меняю цвет фона более чем одной ячейки.Материал для записи файлов работает нормально ... только цвет фона дублируется.

Я изменяю цвет в функции editActionsForRowAt следующим образом:

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    let Action2 = UITableViewRowAction(style: .default, title: "Mark Read", handler: { (action, indexPath) in

// функция продолжает делать вещи перед установкой цвета ...

    if filteredMessageIDforSwipe.count == 0  {

    let selectedCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell

    selectedCell.contentView.backgroundColor = UIColor(hexString: "#ffffff")

Обратите внимание, что я не выбираю ячейку ... скорее, проводя пальцем по экрану, а затем пытаюсь изменить цвет фона ячейки для ячейки, которая была проведена.

Очевидно, я хочу, чтобы только ячейка, на которую я нажал, меняла цвет, а не другую (если у меня более 7 ячеек).

Спасибо!

N.

РЕДАКТИРОВАТЬ: я изменил editActionsForRowAt, как рекомендовано ниже, но без эффекта.

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    selectedRowIndexForReadUnread = indexPath.row

    let Action2 = UITableViewRowAction(style: .default, title: "Mark Read", handler: { (action, indexPath) in

    if filteredMessageIDforSwipe.count == 0 && selectedRowIndexForReadUnread = indexPath.row   {

    let selectedCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell

    selectedCell.contentView.backgroundColor = UIColor(hexString: "#ffffff")

Редактировать: Для справки, вот функция editActionsForRowAt ... Action2 и Action5 актуальны.

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    selectedRowIndexForReadUnread = indexPath.row

    if tableView == self.Nomination2SearchTableView {


        let Action1 = UITableViewRowAction(style: .default, title: "Select", handler: { (action, indexPath) in

            self.Nomination2SearchTableView.isHidden = true
            self.Nomination2TableView.isHidden = false
            NominationState = "Active"

            let SearchObject: Nomination2SearchModel
            SearchObject = Nomination2SearchList[indexPath.row]

            userIDStringforNominationSearch = SearchObject.UserIDString!
            let FullName = SearchObject.Full_Name

            self.FullNameLabel.isHidden = false
            self.FullNameLabel.text = "Showing " + FullName! + "'s Shout Outs"

            self.LoadDataFromNominationafterSearch()
            self.ActiveButton.setTitleColor(.orange, for: .normal)


            let banner = NotificationBanner(title: "Tip", subtitle: "Swipe to select a user.", style: .info)
            banner.haptic = .none
            banner.show()

            //We are setting the editor mode to the opposite of what is displayed in the tableview, because EditorMode text is what is displayed when you swipe the cell.
           // EditorMode = "Set to Complete"

        })
        return [Action1]

    }

    if tableView == self.Nomination2TableView{


        if NominationState == "Active" {


                     let Action2 = UITableViewRowAction(style: .default, title: "Mark Read", handler: { (action, indexPath) in

                        let searchObject9: Nomination2Model
                        searchObject9 = Nomination2List[indexPath.row]
                        let messageIDKey = searchObject9.key


                        let filename = self.getDocumentsDirectory().appendingPathComponent("output.txt")
                        do {

                            let textStringFromFile = try String(contentsOf: filename, encoding: .utf8)

                            var result: [(messageID: String, readStatus: String)] = []

                            // var indexCount = result.count

                            let rows = textStringFromFile.components(separatedBy: "\n")
                            for row in rows {
                                let columns = row.components(separatedBy: ",")
                                result.append((columns[0], columns[1]))
                            }

                            filteredMessageIDforSwipe = result.filter { $0.messageID == (messageIDKey) }

                        }
                        catch{

                        }

                        if filteredMessageIDforSwipe.count == 0   {

                        let selectedCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell
                            // let selectedCellForReadMessages:UITableViewCell = self.Nomination2TableView.cellForRow(at: indexPath)! as! Nomination2TableViewCell
                        selectedCell.contentView.backgroundColor = UIColor(hexString: "#ffffff")

                        // let myReadCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell
                        // myReadCell.NominationNameLabel.textColor = UIColor.lightGray
                        // myReadCell.NominationTextLabel.textColor = UIColor.lightGray

                        let NominationObject: Nomination2Model
                        NominationObject = Nomination2List[indexPath.row]
                        nominationKeyForWhenCellSelected = NominationObject.key
                        self.writeFile()
                        // self.removeRowFromFile()
                        }

                        if filteredMessageIDforSwipe.count > 0 {

                            let alert = UIAlertController(title: "Failure",
                                                          message: "Shout-out is already read!",
                                                          preferredStyle: .alert)
                            alert.addAction(UIAlertAction(title: "OK", style: .default))
                            self.present(alert, animated: true, completion: nil)

                        }

            })



            let Action5 = UITableViewRowAction(style: .default, title: "Mark Unread", handler: { (action, indexPath) in

                let searchObject9: Nomination2Model
                searchObject9 = Nomination2List[indexPath.row]
                let messageIDKey = searchObject9.key


                let filename = self.getDocumentsDirectory().appendingPathComponent("output.txt")
                do {

                    let textStringFromFile = try String(contentsOf: filename, encoding: .utf8)

                    var result: [(messageID: String, readStatus: String)] = []

                    // var indexCount = result.count

                    let rows = textStringFromFile.components(separatedBy: "\n")
                    for row in rows {
                        let columns = row.components(separatedBy: ",")
                        result.append((columns[0], columns[1]))
                    }




                    filteredMessageIDforSwipe = result.filter { $0.messageID == (messageIDKey) }

                }
                catch{

                }

                if filteredMessageIDforSwipe.count > 0 {


                    let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
                    selectedCell.contentView.backgroundColor = UIColor(hexString: "#fcf0e5")

                    // let myCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell
                    // myCell.NominationNameLabel.textColor = UIColor.orange
                    // myCell.NominationTextLabel.textColor = UIColor.black

                    let NominationObject: Nomination2Model
                    NominationObject = Nomination2List[indexPath.row]
                    nominationKeyForWhenCellSelected = NominationObject.key
                    // self.writeFile()
                    self.removeRowFromFile()
                }

                if filteredMessageIDforSwipe.count == 0 {

                    let alert = UIAlertController(title: "Failure",
                                                  message: "Shout-out is already unread!",
                                                  preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .default))
                    self.present(alert, animated: true, completion: nil)

                }

            })

            Action2.backgroundColor = UIColor.lightGray
            Action5.backgroundColor = UIColor.blue
            return[Action2, Action5]
        }



     if NominationState == "Approve"{

     let Action3 = UITableViewRowAction(style: .default, title: NominationState, handler: { (action, indexPath) in


            let searchObject9: Nomination2Model
            searchObject9 = Nomination2List[indexPath.row]

            ForName  = searchObject9.ForName!
            FromName = searchObject9.FromName!
            ForWhat = searchObject9.ForWhat!
             key = searchObject9.key!
             ForUserID = searchObject9.ForUserID!
             FromUserID = searchObject9.FromUserID!
             PointsGifted = searchObject9.PointsGifted!
             NominationText = searchObject9.NominationText!
            ImageNameNominations = searchObject9.ImageNameString!
            ImageURLNominations = searchObject9.ImageURL!


            databaseReference = Database.database().reference()

            databaseReference.child("Users").child(FromUserID).observeSingleEvent(of: DataEventType.value, with: { (snapshot) in

                let value = snapshot.value as? NSDictionary

                let CurrentPointsRedeemed = value?["Points_Redeemed"] as? Int
                let CurrentPointsBalance = value? ["Points_Balance"] as? Int

                let NewPointsRedeemed = CurrentPointsRedeemed! + PointsGifted

                let NewPointsBalance = CurrentPointsBalance! - PointsGifted



                if NewPointsBalance >= 0{

                    databaseReference.child("Users").child(FromUserID).updateChildValues(["Points_Redeemed": NewPointsRedeemed])

                    databaseReference.child("Users").child(FromUserID).updateChildValues(["Points_Balance": NewPointsBalance])



                    self.postToFirebase()
                    self.giftPoints()
                    self.pendingCount()

                    Nomination2List.remove(at: indexPath.row)
                    tableView.deleteRows(at: [indexPath], with: .fade)

                }

                if NewPointsBalance <= 0{

                    let alert = UIAlertController(title: "Nominations",
                                                  message: "Not Enough Points for approval",
                                                  preferredStyle: .alert)

                    alert.addAction(UIAlertAction(title: "OK", style: .default))

                    self.present(alert, animated: true, completion: nil)


                }

        })


     })

        Action3.backgroundColor = UIColor.blue
        return[Action3]

        }
        //here

        //Action2.backgroundColor = UIColor.blue
        //return[Action2]
     else{
        return [UITableViewRowAction]()
        }
    }
    else {
        return [UITableViewRowAction]()
    }

}

Ответы [ 4 ]

0 голосов
/ 29 января 2019

Когда вы прокручиваете вниз, ваше табличное представление повторно использует ранее загруженные ячейки, сохраняя цвет фона, вам нужно сбросить цвет по умолчанию в:

override func prepareForReuse() {
    // set the color to default
}
0 голосов
/ 29 января 2019

Попробуйте это:

var selectedIndexPath: [IndexPath]?

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedIndexPath.append(indexPath)
tableView.reloadData()}

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.contentView.backgroundColor = selectedIndexPath?.contains(indexPath) ? UIColor(hexString: "#efefef") :  UIColor.clear}
0 голосов
/ 29 января 2019

Вы можете управлять этим с помощью didSelectRow и cellForRow делегировать методы UITableView.Используйте одну переменную для управления выбранным индексом строки.Используйте следующий код:

var selectedRowIndex:Int = -1

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {       
        let cell = self.Nomination2TableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as Nomination2TableViewCell!
        if self.selectedRowIndex == indexPath.row {
            cell.contentView.backgroundColor = UIColor(hexString: "#efefef")
        } else {
            cell.contentView.backgroundColor = UIColor(hexString:"defaultColor")
        }    
        return cell
    }

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.selectedRowIndex = indexPath.row            
        self.Nomination2TableView.reloadRows(at:[indexPath], with: .none)
    }

Когда вы редактировали свой вопрос, вы можете попробовать следующий метод:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
DispatchQueue.main.async {
    self.Nomination2TableView.beginUpdates()    
    self.selectedRowIndex = indexPath.row            
    self.Nomination2TableView.reloadRows(at:[indexPath], with: .none)
    self.Nomination2TableView.endUpdates()      
}

    let Action2 = UITableViewRowAction(style: .default, title: "Mark Read", handler: { (action, indexPath) in
0 голосов
/ 29 января 2019

Ячейки табличного представления используются повторно, поэтому цвет фона других ячеек меняется.

Существует хороший фрагмент кода для взлома с помощью swift , который делает именно то, что вам нужно.Я использую этот фрагмент в моих собственных проектах тоже.

Так что в вашем случае это будет выглядеть так:

    let backgroundView = UIView()
    backgroundView.backgroundColor = UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.0)
    cell.selectedBackgroundView = backgroundView

Замените ваш код этим, и я думаю, что все будет в порядке.Надеюсь, это поможет.

РЕДАКТИРОВАТЬ:

Чтобы изменить только цвет ячейки прокрутки, вы можете попытаться вставить оператор else после вашего оператора if.Вы можете попробовать это:

let selectedCell = self.Nomination2TableView.cellForRow(at: indexPath) as! Nomination2TableViewCell

if filteredMessageIDforSwipe.count == 0  {

selectedCell.contentView.backgroundColor = UIColor(hexString: "#ffffff")
} else {
selectedCell.contentView.backgroundColor = UIColor.white 
//or whatever the color of the background is by default
}

Дайте мне знать, если это не решит это!

РЕДАКТИРОВАТЬ 2:

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

В приведенном ниже решении я не использовал те же самые объекты и переменные, которые вы используететак как это было бы трудно воссоздать без вашего полного кода.Вместо этого это логика , которую вы можете реализовать в своем собственном решении.Таким образом, кажется, что вы сохраняете выбранные ячейки indexPaths в filteredMessageIDforSwipe - поэтому вам следует перебрать этот массив и установить цвет для ячеек с соответствующими путями индекса.Важно установить цвет фона ячейки по умолчанию до того, как вы вызовете цикл for.

Вот мой пример ViewController:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

let userDefaults = UserDefaults.standard

let testArray = ["Test1", "Test2", "Test3", "Test4", "Test5", "Test6", "Test7", "Test8", "Test9", "Test10", "Test11", "Test12", "Test13", "Test14", "Test15", "Test16", "Test17", "Test18", "Test19", "Test20"]

var selectedCellIndexPaths = [Int]()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self
    if let values = userDefaults.value(forKey: "IndexPathsArray") as? Array<Int> {
    selectedCellIndexPaths = values
    }
    print("selected", selectedCellIndexPaths)

}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    cell.textLabel?.text = testArray[indexPath.row]

    cell.backgroundColor = UIColor.white

    for indx in selectedCellIndexPaths {
        if indexPath.row == indx {
            cell.backgroundColor = UIColor.red
        }
    }

    return cell
}

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

            let cell = tableView.cellForRow(at: indexPath)

    let action = UITableViewRowAction(style: .default, title: "Mark Read") { (action, indexPath) in

        cell?.backgroundColor = UIColor.red

        self.selectedCellIndexPaths.append(indexPath.row)

        self.userDefaults.set(self.selectedCellIndexPaths, forKey: "IndexPathsArray")
        print(self.selectedCellIndexPaths)
    }

    return [action]

}

}

Дайте мне знать, если вам нужна дополнительная помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...