When I tap the cell of TableVie in the VieController, I was able to display the information in the cell in the RegisterViewController in the previous question, but I would like to create a new ListViewController and tap the button in the upper right corner of the RegisterViewController.
The ViewController and ListViewController also allow TabBar movement.
I don't want to go back to Navigation from ListViewController because RegisterView is an accessory to ViewController, so I want to add cells with information to ListViewController but not transition after registration.
I will pass the value without transition, so I will pass the value only by UD, but I would like to use NSCoding because it is CustomCell's UD, so I would like to use NSKeyedUnarchiver.
When the Register item is addedListTapped, I put it in the ListView list and made TableViewcell listNameLabel and listDateLabel with xib, so I would like to display it on it, but it does not appear as a candidate, so please tell me how to write it.
ItemModelClass
class Item:NSObject,NSCoding {
var name —String
vardate:String
init(name:String, date:String) {
self.name = name as String
self.date=date as String
}
funcencode (with code:NSCoder) {
code.encode(self.name, forKey: "name")
code.encode(self.date, forKey: "date")
}
required init?(coder:NSCoder) {
self.name=coder.decodeObject(forKey: "name") as!String
self.date=coder.decodeObject(forKey: "date") as!String
}
}
ViewController
class ViewController:UIViewController {
@IBOutlet weak variable:UITableView!
variables: Item = Item()
override func viewDidLoad(){
super.viewDidLoad()
table.register (TableViewCell.nib(), forCellReuseIdentifier: TableViewCell.identifier)
table.delegate=self
table.dataSource=self
self.setupItems()
}
func setupItems(){
items = [Items(name:"a", date:"1"), item(name:"b", date:"2", item(name:"c", date:"3", item(name:"d", date:"4", item(name:"e", date:"5"),]
}
}
hereinafter abbreviated
RegisterViewController
class RegisterViewController:UIViewController {
@IBOutlet weak var registeredNameLabel:UILabel!
@IBOutlet weak var registeredDateLabel:UILabel!
@IBOutlet var addListButton: UIBarButtonItem!
// Item type
variable item —Item!
override func viewDidLoad(){
super.viewDidLoad()
// Buttons to add to MovieList
addListButton=UIBarButtonItem(title: "Add to List", style: .plain, target:self, action:#selector(addListTapped(_:)))
self.navigationItem.rightBarButtonItems= [addListButton]
registeredNameLabel.text=item.name
registeredDateLabel.text=item.date
}
@objc funcaddListTapped(_sender:UIBarButtonItem){
print("Tapped")
// Questions
}
ListViewController
classListViewController:UIViewController {
var list: Item = [ ]
var allList: Item = [ ]
var selectedList: Item = [ ]
@IBOutlet weak variable:UITableView!
@ IBAction function segmentSelcted(_sender:UISegmentedControl){
switch sender.selectedSegmentIndex{
case0:
list = allList
case1:
list = selectedList
default:
fatalError("case cannot cover)")
}
table.reloadData()
}
override func viewDidLoad(){
super.viewDidLoad()
table.delegate=self
table.dataSource=self
// Read UD
}
}
extensionListViewController:UITableViewDelegate,UITableViewDataSource{
functableView(_tableView:UITableView, numberOfRowsInSection section:Int) - > Int{
list.count
}
functableView(_tableView:UITableView, cellForRowAtindexPath:IndexPath) - >UITableViewCell{
letcell=tableView.dequeueReusableCell (with Identifier: ListTableViewCell.identifier, for:indexPath) as!ListTableViewCell
cell.setcell (item:list [indexPath.row])
return cell
}
}
ListTableViewCell
func setcell(item:Item){
self.listNameLabel.text=item.name as String
self.listDateLabel.text=item.date as String
}
Now, as I wrote in the comment, it's not particularly difficult to create Singleton, so the answer to the question that says "Save with UserDefaults" is a bit of a pushover.
Using Singleton without UserDefaults
I would like to write an answer with this policy.
Now, for those who have just started iOS programming, defining their own classes (other than UIViewController
and UIView
) may seem difficult to understand, but if you get used to it rather than learn it, you'll find it not that difficult.
Basically, all you have to do is write classes in this format.
class MyData{
// Define a singleton named for `UserDefaults`
staticlet standard=MyData()
// Other required features are described
//...
}
As far as the comments are concerned,
ListViewController
in RegisterViewControllerThis seems to be the main focus, so we will move allList
and selectedList
of ListViewController
to MyData
.
class MyData{
// Define a singleton named for `UserDefaults`
staticlet standard=MyData()
// Variables accessed by multiple view controllers are summarized together with highly relevant variables
private(set)var allList: Item = [ ]
private(set) var selectedList: Item = [ ]
funcadd(_item:Item, isSelected:Bool=false){
allList.append(item)
if isSelected {
selectedList.append(item)
}
}
// To put a part of `allList` into `selectedList`, define it here if you need any action
//...
}
private(set)
is attached because it can be inconsistent if array operations are performed at various locations without permission.
Singleton property names such as shared
and default
may be popular(?), but UserDefaults
which also use Singleton seems to have no resistance, so it is set to standard
.
Any information you can handle on your computer is "data", so MyData
is a pretty bad naming sense.Please use a better name for the actual app.
private(set)
is attached because it can be inconsistent if array operations are carried out in various places.
shared
and default
are popular properties names for Singleton, but there seems to be no resistance to using UserDefaults
, which also uses Singleton, so it is set to standard
.
Any information you can handle on your computer is "data", so MyData
is a pretty bad naming sense.Please use a better name for the actual app.
Using MyData
above, the RegisterViewController
looks like this:
class RegisterViewController:UIViewController {
@IBOutlet weak var registeredNameLabel:UILabel!
@IBOutlet weak var registeredDateLabel:UILabel!
@IBOutlet var addListButton: UIBarButtonItem!
// Item type → Avoid Implicitly Unwrapped as much as possible
varitem —Item?//<-
override func viewDidLoad(){
super.viewDidLoad()
// Buttons to add to MovieList
addListButton=UIBarButtonItem(title: "Add to List", style: .plain, target:self, action:#selector(addListTapped(_:)))
self.navigationItem.rightBarButtonItems= [addListButton]
// It is better to process data from other screens with 'viewWillAppear' instead of 'viewDidLoad'
// registeredNameLabel.text=item?.name
// registeredDateLabel.text=item?.date
}
override func viewWillAppear(_animated:Bool){
super.viewWillAppear(animated)
guard letter item=item else {
print("item is nil")
// Other error handling if necessary
return
}
// Process data from other screens here
registeredNameLabel.text=item.name
registeredDateLabel.text=item.date
}
@objc funcaddListTapped(_sender:UIBarButtonItem){
print("Tapped")
// Questions
guard letter item=item else {
print("item is nil")
// Other error handling if necessary
return
}
// Perform data operations only through the 'MyData' method
MyData.standard.add (item, isSelected: false)
}
}
item
data type from Item!
to Item?
. It is recommended that you remember that you do not use Implicitly Unwrapped Optional (!
) except for a regular pattern like @IBOutlet
.Similarly, replacing the ListViewController
with the MyData
version will look like this.
classListViewController:UIViewController {
// Instead of copying arrays whenever there is a change, "calculate" one of the necessary arrays each time
var list: Item {
switch segmentedControl.selectedSegmentIndex{
case0:
return MyData.standard.allList
case1:
return MyData.standard.selectedList
default:
fatalError("case cannot cover)")
}
}
// Move variables accessed by multiple view controllers to 'MyData' with highly relevant variables
// var allList: Item = [ ]
// var selectedList: Item = [ ]
@IBOutlet weak variable:UITableView!
// Add IBOutlet to make `list` a calculated property, keep it connected correctly
@IBOutlet weak var segmentedControl:UISegmentedControl!
@ IBAction function segmentSelcted(_sender:UISegmentedControl){
Making //`list` a computational property eliminates the need to copy arrays here
// switch sender.selectedSegmentIndex{
// case0:
// list = allList
// case1:
// list = selectedList
// default:
// fatalError("case cannot cover)")
// }
// However, `table.reloadData()` is required
table.reloadData()
}
override func viewDidLoad(){
super.viewDidLoad()
table.delegate=self
table.dataSource=self
// All the necessary data is stored in 'MyData' so there is no need to load it at this time.
}
If you do not call `table.reloadData()` in // `viewWillAppear(_:)`, the screen may not be updated.
override func viewWillAppear(_animated:Bool){
super.viewWillAppear(animated)
table.reloadData()
}
}
list
to computational properties is not a must, and I can't say "better" from any point of view, but the condition of "must update multiple arrays consistently" is very difficult to manage as the program grows.I omitted the part of the code that was omitted in the question, but I don't think it's necessary to make such a big correction. What do you think?
It may be a binding issue that requires the use of UserDefaults
, but if not, I would definitely like you to try it.
567 rails db:create error: Could not find mysql2-0.5.4 in any of the sources
607 Uncaught (inpromise) Error on Electron: An object could not be cloned
568 Who developed the "avformat-59.dll" that comes with FFmpeg?
886 When building Fast API+Uvicorn environment with PyInstaller, console=False results in an error
599 GDB gets version error when attempting to debug with the Presense SDK (IDE)
© 2024 OneMinuteCode. All rights reserved.