Пользовательские изображения ячеек UITableView путаютсяIOS

Программируем под IOS
Ответить
Anonymous
 Пользовательские изображения ячеек UITableView путаются

Сообщение Anonymous »

У меня возникла проблема с перепутыванием изображений из-за повторного использования ячеек. Я решил эту проблему (по крайней мере, мне казалось, что я решил), выполнив проверку внутри ячейки на личность пользователя, чтобы свойство идентификации соответствовало URL-адресу изображения, полученному с сервера. Однако даже при этом мои изображения по-прежнему путаются между ячейками. Это мой код в пользовательском классе ячеек:

Код: Выделить всё

import UIKit

class AllUsersListCell: UITableViewCell {
var preImageRequestIdentity: String = ""

var imgUrl: String? {
didSet {
loadImageFromUrl()
}
}

let imgIcon: UIImageView = {
let ic = UIImageView()
ic.contentMode = .scaleAspectFill
ic.layer.cornerRadius = 5.0
ic.clipsToBounds = true
ic.tintColor = .lightGray

ic.backgroundColor = APP_YELLOW_COLOR

return ic
}()

let lblCaption: UILabel = {
let ic = UILabel()
ic.font = .appFontWithSize(size: 22.0)
return ic
}()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

backgroundColor = .clear
selectionStyle = .none

addSubview(imgIcon)
imgIcon.translatesAutoresizingMaskIntoConstraints = false
imgIcon.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, constant: 24.0).isActive = true
imgIcon.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
imgIcon.widthAnchor.constraint(equalToConstant: 34.0).isActive = true
imgIcon.heightAnchor.constraint(equalTo: imgIcon.widthAnchor).isActive = true

addSubview(lblCaption)
lblCaption.translatesAutoresizingMaskIntoConstraints = false
lblCaption.leftAnchor.constraint(equalTo: imgIcon.rightAnchor, constant: 16.0).isActive = true
lblCaption.centerYAnchor.constraint(equalTo: imgIcon.centerYAnchor).isActive = true
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func loadImageFromUrl() {

guard imgUrl != "" else {
return
}

guard let imageUrl = imgUrl, let url = URL(string: imageUrl) else {
print("Invalid URL string")
return
}

URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Failed to load image: \(error.localizedDescription)")
return
}

guard let data = data, let image = UIImage(data: data) else {
print("Invalid image data")
return
}

DispatchQueue.main.async {
self.imgIcon.image = image
}
}.resume()
}

func callProfileImageApi(identity: String) {
self.preImageRequestIdentity = identity
self.imgUrl = ""
Api.sharedInstance.httpGet(url: getUserProfileImageUrl(forUser: identity)) { (response, error) in

guard let r = response else {
print("response fell through")
return
}

if r.value(forKey: "image_url") as! String == ""  {
self.imgUrl = ""

} else {
let iu = r.value(forKey: "image_url") as! String
let fullImageUrlString = "\(getBaseUrl())\(iu)"

if self.preImageRequestIdentity == identity {
self.imgUrl = fullImageUrlString
} else {

self.imgUrl = ""
self.callProfileImageApi(identity: identity)
}
}
}

}
}
и это код на реальной странице, которая является делегатом табличного представления:

Код: Выделить всё

//
//  AllUsersChatListVC.swift
//
//
//

import UIKit
import CloudKit
import TwilioConversationsClient
import SwiftUI

class AllUsersChatListVC: GosViewController {

// Tapped other user's identity
var otherUserIdentity: String!

var tableView: UITableView!

var pullRefresher:UIRefreshControl = UIRefreshControl()// Added for table view pull to referesh so that we don't have to kill and start again the app
var arrTwillioUsers = [User]()
var aLabel: UILabel!

var isInitiallyLoading = false

override func viewDidLoad() {
super.viewDidLoad()

let defaults = UserDefaults.standard
if isUserLoggedIn() {
if let identity = defaults.string(forKey: kUserIdentity) {
currentUserIdentity = identity
} else {
currentUserIdentity = "UNKNOWN"
}
}

self.pullRefresher.tintColor = .black
self.pullRefresher.shadowColorOverAll = .black
view.backgroundColor = .white

configureNavBar()
configureSpacingLabel()
configureUserTableView()

self.showLoading()
self.isInitiallyLoading = true
callGetAllUsersAPI()

}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.tintColor = APP_YELLOW_COLOR // DEV:  see if this causes color issues on dragging the screen up/down on all chat page
navigationController?.hidesBarsOnSwipe = false
navigationController?.hidesBarsOnTap = false
navigationController?.hidesBarsWhenKeyboardAppears = false
navigationController?.hidesBarsWhenVerticallyCompact = false
navigationController?.navigationBar.barStyle = .default
navigationController?.navigationBar.isHidden = false
navigationItem.setHidesBackButton(true, animated: true)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

}

// Label that serves so the color doesn't change on the nav bar when dragged down
func configureSpacingLabel() {
aLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
aLabel.center = CGPoint(x: 100, y: 10)
aLabel.textAlignment = .left
aLabel.text = "Spacing label"

view.addSubview(aLabel)
}

func configureUserTableView() {

tableView = UITableView()
tableView.delegate = self
tableView.dataSource = self
tableView.register(AllUsersListCell.self, forCellReuseIdentifier: reuseId)
tableView.contentInset = .init(top: 16.0, left: 0, bottom: 0, right: 0)
tableView.backgroundColor = .white

view.addSubview(tableView)

tableView.tableFooterView = UIView(frame: .zero)
tableView.layer.backgroundColor = UIColor.white.cgColor

tableView.translatesAutoresizingMaskIntoConstraints = false

tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true

// pull to refresh added on tableview
self.pullRefresher.addTarget(self, action: #selector(self.onSwipeRefresh), for:  .valueChanged)
self.tableView.refreshControl = self.pullRefresher
self.pullRefresher.tintColor = .black
}

// swipe lister of pull to refresh
@objc func onSwipeRefresh() {
print("in inSwipeRefresh")
self.callGetAllUsersAPI()

}

func configureNavBar() {

let topLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
topLabel.textAlignment = .center
topLabel.text = currentUserIdentity
topLabel.font = UIFont(name: GOS_FONT_NAME, size: vcTitleSize)

navigationItem.titleView = topLabel
self.navigationController?.setStatusBar(backgroundColor: APP_YELLOW_COLOR)
}

func callGetAllUsersAPI() {
if offline  {
let user : User = User()
user.identity = "fadil"
arrTwillioUsers.append(user)

let user2 : User = User()
user2.identity = "Memara"
arrTwillioUsers.append(user2)

self.tableView.reloadData()

self.pullRefresher.endRefreshing()
self.hideLoading()

} else {

Api.sharedInstance.httpGet(url: WS_URL(url: GetAllUsersAPI)) { [weak self] (response, error) in

self?.pullRefresher.endRefreshing()

if self?.isInitiallyLoading ?? true {
self?.hideLoading()
self?.isInitiallyLoading = false
}

if (error == nil) {
self?.manageUserResponse(dict: response)
} else {

self!.showAlert(title: "Error", message: error?.domain)
}
}
}
}

func manageUserResponse(dict : NSDictionary?) {
guard let arr = dict?.value(forKey: param_users) else { return }

let arrUsers = arr as! [Any]
arrTwillioUsers.removeAll()
if arrUsers.count > 0 {
for userDictionary in arrUsers {
let user : User = User.init(dictionary: userDictionary as! NSDictionary)!
arrTwillioUsers.append(user)
}
}

arrTwillioUsers = arrTwillioUsers.filter({$0.identity != currentUserIdentity})
arrTwillioUsers = arrTwillioUsers.sorted(by: { $0.identity ?? "" < $1.identity ?? ""})

self.tableView.reloadData()

}

func handleClick(otherUser: String) {
print("in handleClick")
self.otherUserIdentity = otherUser

if offline {
prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
} else {
self.showLoading()
if isTokenExpired() {
ConversationsManager.shared.refreshAccessToken() {
self.prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
}
} else {
prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)

}
}
}

func prepareAndPushChatPage(cur: String, oth: String) {
ConversationsManager.shared.initializeConversationManager(token: getToken(), conversationDelegate: self) {
self.loadChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
}

}

func loadChatPage(cur: String, oth: String) -> Void {

guard oth != "" && cur != ""  else {
return
}

let cvc = ChatVC()
cvc.currentUserIdentity = cur
cvc.currentChatPartnerIdentity = oth
// Prevent reopening for same user
//openChatWithUser = ""
DispatchQueue.main.async {
self.navigationController?.pushViewController(cvc, animated: true)
self.hideLoading()
}

self.chatVC = cvc
}

}

// MARK: - TableView Delegate
extension AllUsersChatListVC: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrTwillioUsers.count
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.handleClick(otherUser: arrTwillioUsers[indexPath.row].identity!)

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseId, for: indexPath) as! AllUsersListCell
let objUser = arrTwillioUsers[indexPath.row]
cell.lblCaption.text = objUser.identity // actual text for a user, for a row in the users chat list
cell.lblCaption.font = UIFont(name: GOS_FONT_NAME, size: 22)

cell.callProfileImageApi(identity: objUser.identity!)

tableView.rowHeight = 60
return cell
}

}
что я делаю не так?

Подробнее здесь: https://stackoverflow.com/questions/790 ... ges-mix-up
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»