(jawaban ini bukan tentang arsitektur aplikasi, hanya memposting solusi sederhana untuk masalah penulis)
Anda mengatakan bahwa tombol Anda mewakili status 'ikuti' model Anda (Profil). Anda mungkin ingin memiliki model yang mewakili profil:
class Profile {
var following : Bool = false
}
ViewController
pertama Anda mungkin akan terlihat seperti ini:
class ProfileListViewController : UIViewController, ProfileDetailsViewControllerDelegate {
var profiles : [Profile] = [...]
func userDidChangeProfileInfo(_ profile : Profile)() {
(...)
}
}
Saat Anda membuka profil, Anda akan memanggil sesuatu seperti ini di ProfileListViewController
Anda:
func openProfileDetails(at indexPath: IndexPath) {
let profile = profiles[indexPath.row]
let detailsViewController = ProfileDetailsViewController.getInstance()
detailsViewController.profile = profile
detailsViewController.delegate = self
self.navigationController?.pushViewController(detailsViewController, animated: true)
}
bidang delegate
adalah protokol yang terlihat seperti ini dan diimplementasikan dalam kode di atas:
protocol ProfileDetailsViewControllerDelegate : class {
func userDidChangeProfileInfo(_ profile : Profile)
}
ProfileDetailsViewController
:
class ProfileDetailsViewController : UIViewController {
var profile: Profile?
weak var delegate : ProfileDetailsViewControllerDelegate?
func didTapFollowButton() {
profile.following = true
delegate?.userDidChangeProfileInfo(profile)
}
}
kembali ke ProfileListViewController
Anda, metode delegate
akan dipanggil dan Anda dapat memuat ulang baris Anda (atau seluruh tampilan tabel jika Anda mau):
func userDidChangeProfileInfo(_ profile : Profile)() {
if let row = profiles.firstIndex(where: { $0 == profile }) {
tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .automatic)
}
}
Selanjutnya sel akan dibuat ulang pada indeks ini sehingga metode cellForRowAt
akan dipanggil. Anda dapat mengatur sel Anda lagi berdasarkan perubahan pada model Anda (mengubah teks, gaya, mengembalikan sel yang berbeda, dll, apa pun yang sesuai dengan keinginan Anda dan sesuai dengan kasus penggunaan Anda):
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(...)
let profile = profiles[indexPath.row]
if profile.following {
cell.type = .following
} else {
cell.type = .notFollowing
}
return cell
}
Sel itu sendiri bisa terlihat seperti ini:
enum ProfileTableCellMode {
case following
case notFollowing
}
class ProfileTableCell : UITableViewCell {
@IBOutlet weak var followButton : UIButton!
var state: ProfileTableCellMode = .notFollowing { //default value
didSet {
onStateUpdated()
}
}
func onStateUpdated() {
switch state {
case .following:
followButton.setTitle("Unfollow", for: .normal)
case .notFollowing:
followButton.setTitle("Follow", for: .normal)
}
}
}
Anda juga dapat melewati semua hal pendelegasian dan langsung melakukan hal seperti ini di ProfileListViewController
:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView.reloadData()
}
Jadi seluruh tabel dimuat ulang ketika ProfileListViewController
kembali menjadi pengontrol teratas.
Hal terpenting di sini adalah memisahkan UI (antarmuka pengguna) dari status (model, dll). UI harus merender/memperbarui dirinya sendiri berdasarkan status dan tidak boleh menangani logika bisnis apa pun selain meneruskan 'saya diklik, tolong tangani' ke logika tersebut.
person
FruitAddict
schedule
01.10.2018