I have a simple tableview within my Settings VC. There are two different cases, either the logged in user is an employee or the admin. The Admin is able to add Users to the organization, so he sees two sections with one row each (add user and log out) while a normal employee only sees one section with one row (log out). To manage the indexPaths I have these structs:
struct Indexes {
struct AddEmployee {
static let row = 0
static let section = isEmployee() ? -1 : 0
static func indexPath() -> IndexPath {
return IndexPath(row: row, section: section)
}
}
struct SignOut {
static let row = 0
static let section = isEmployee() ? 0 : 1
static func indexPath() -> IndexPath {
return IndexPath(row: row, section: section)
}
}
}
Within my TableView delegate I got these Methods:
func numberOfSections(in tableView: UITableView) -> Int {
return isEmployee() ? 1 : 2
}
and
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
if (indexPath == Indexes.AddEmployee.indexPath()) {
cell.textLabel?.text = "Add Employee"
} else if (indexPath == Indexes.SignOut.indexPath()) {
cell.textLabel?.text = "Log out"
}
return cell
}
The problem now is, when I sign out as Admin and Sign in as Employee (or vice versa), the static
variables of the structs are still initialized and the fact, that the isEmployee()
return value has changed doesn't matter because the variables aren't reloaded, so I have wrong amounts of cells. Is there a possibility to force the structs to reload their static variables?
There is not a way to force the structs to reload their static stored constants, but you simply need to use static computed variables instead.
A computed variable looks like the following:
static var section: Int {
get {
return isEmployee() ? -1 : 0
}
}
Computed variables are not actually stored, but computed each time you call them. This won't be a problem unless your logic takes a long time to execute, which yours shouldn't. Even though this is labeled var
and not let
, it will still be read-only because you have only specified a getter (you could have specified a setter with a set
block below the get
block).
As a shortcut, you don't need to explicitly show the get
keyword and braces when you only want a getter, so you can get rid of those. You're left with:
struct Indexes {
struct AddEmployee {
static let row = 0
static var section: Int {
return isEmployee() ? -1 : 0
}
static func indexPath() -> IndexPath {
return IndexPath(row: row, section: section)
}
}
struct SignOut {
static let row = 0
static var section: Int {
return isEmployee() ? 0 : 1
}
static func indexPath() -> IndexPath {
return IndexPath(row: row, section: section)
}
}
}
If you wanted, you could even convert indexPath
to a computed variable rather than a function and it would do the same thing. A common convention in Swift is to use computed variables when no arguments are required and the logic to get the result is trivial and therefore won't take long.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With