Cannot assign value of type '[CollectionViewController.ViewCell]' to type '[CollectionViewController 2.ViewCell2]' - swift5

I need to pass a structure reference from one view controller to another.
Here is my code's part:
//In CollectionViewController.swift
struct ViewCell{
var lbl : String
var details: String
}
var cellDetails = [ViewCell]()
//In a action method of button tapped
let vc = CollectionViewController2.init(nibName:
"CollectionViewController2", bundle: nil)
vc.cellDetails2 = self.cellDetails
self.navigationController?.pushViewController(vc, animated: true)
//In CollectionViewController2.swift ---**
struct ViewCell2{
var lbl : String
var details: String
}
var cellDetails2 = [ViewCell2]()
code shows me error:
"Cannot assign value of type '[CollectionViewController.ViewCell]' to type '[CollectionViewController2.ViewCell2]'".
But why? How can I resolve it?

Related

How to access struct values inside of another struct in Swift 4?

I currently have
struct cellData {
var opened = Bool()
var title = String()
var iconName = String()
var sectionData = [Any]()
}
struct SectionData {
var subTitle: String
var iconName: String
}
And in another function I call:
let test = tableViewData[indexPath.section].sectionData[dataIndex]
print(test)
Which outputs:
SectionData(subTitle: "Terms", iconName: "")
How do I access the subTitle value because doing test.subTitle throws the following error:
Value of type 'Any' has no member 'subTitle'
This is because, in your line var sectionData = [Any](), you have defined the type as Any. So when you access it via tableViewData[indexPath.section], you get back the value as Any.
You should change var sectionData = [Any]() to var sectionData = [SectionData]()
Otherwise, once you get the value from tableViewData[indexPath.section], you can convert to SectionData and then access the value.
Change your sectionData array to an array of SectionData like so: var sectionData = [SectionData](). Once you do this, you'll able to access it by calling: tableViewData[indexPath.section].sectionData[dataIndex].subTitle

Cannot get value of switch from different VC Swift

I want to access switch value with the code below. I get nil value. From the second View controller I get settings value to display content according to the value - englishRef.
SetConViewController is my settings view controller from where I want to get my value.
let languageSettingsRef = SetConvViewController()
var englishRef = ""
// Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
if languageSettingsRef.swithEnglish.isOn{
englishRef = "yes"
}
In the View Controller below, there are switches for the settings
class SetConvViewController: UIViewController {
var conversationSettingsReference: DatabaseReference!
let userID = Auth.auth().currentUser?.uid
var engS = "engS"
var engGoster = ""
#IBOutlet weak var swithEnglish: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
if let eng2 = defaults.value(forKey: engS) {
swithEnglish.isOn = eng2 as! Bool
}
}
let defaults = UserDefaults.standard
#IBAction func switchEng(_ sender: UISwitch) {
defaults.set(sender.isOn, forKey: engS)
}
}
I get nil when I want to access value from this class.
First It's nil because you don't load the VC from storyboard or xib
Second this line
let languageSettingsRef = SetConvViewController()
is not the presented one , so use delegate or any other observing technique to get current value of the presented VC
//
class SettingsViewController: UIViewController {
var setVc:SetConvViewController?
}
when you present SettingsViewController with with segue / push , set
settInstance.setVc = self
then ask the var about the switch value
if self.setVc.swithEnglish.isOn{
englishRef = "yes"
}
Making the var as Bool is another better option

How to declare getter for a swift class field?

I have below definition of a getter in a swift class. I want to check whether the value is nil, if yes create a new instance; otherwise return that value. I am now getting into recursive call since I call self.userHomeNvController inside the getter method. I wander how I should achieve this in swift.
var userHomeNavController:UINavigationController? {
get {
var ctr:UINavigationController? = self.userHomeNavController
if self.userHomeNavController == nil{
ctr = self.storyboard?.instantiateViewControllerWithIdentifier("UserHomeNavigationController") as? UINavigationController
}
return ctr
}
}
Use a lazy property initialized by running a closure:
lazy var userHomeNavController: UINavigationController? = {
let controller = self.storyboard?.instantiateViewControllerWithIdentifier("UserHomeNavigationController") as? UINavigationController
return controller
}()

How to pass data from AKSwiftSlideMenu menu to a UIViewController in Swift?

Hey guys I am using AKSwiftSlideMenu for slide menu functionality in project and I wonder if is there a way so that I can change the destination ViewController title when I segue to it from the Menu? I tried this code but is not passing the data to the destination:
func slideMenuItemSelectedAtIndex(index: Int32) {
let topViewController : UIViewController = self.navigationController!.topViewController!
print("View Controller is : \(topViewController) \n", terminator: "")
switch(index){
case 0:
print("Note\n", terminator: "")
var nextVC = AddSubcategoryVC()
nextVC.categoryName = "Note"
self.openViewControllerBasedOnIdentifier("AddSubcategoryVC")
print("On menu the cat is: \(nextVC.categoryName)")
break
default:
print("default\n", terminator: "")
}
}
On the destination viewcontroller I have this variable that is to get the data from the Menu:
var categoryName = ""
and it is returning 'nil'. I also tried doing this:
var categoryName : String!
and this:
var categoryName = String()
all returning 'nil'.
You have created new object of view controller.
Replace this code :
var nextVC = AddSubcategoryVC()
nextVC.categoryName = "Note"
self.openViewControllerBasedOnIdentifier("AddSubcategoryVC")
with
let destViewController = self.storyboard!.instantiateViewControllerWithIdentifier("AddSubcategoryVC") as! AddSubcategoryVC
destViewController.categoryName = "Note"// You have to pass your data with view controller witch will open
let topViewController : UIViewController = self.navigationController!.topViewController!
if (topViewController.restorationIdentifier! == destViewController.restorationIdentifier!){
print("Same VC")
} else {
self.navigationController!.pushViewController(destViewController, animated: true)
}

Call a func from another class in swift

I would like to call a function which is coded on another class.
So far I have made a struct on the file structs.swift for my data:
struct defValues {
let defCityName: String
let loadImages: Bool
init(defCity: String, loadImgs: Bool){
self.defCityName = defCity
self.loadImages = loadImgs
}
}
I have made the file Defaults.swift containing:
import Foundation
class DefaultsSet {
let cityKey: String = "default_city"
let loadKey: String = "load_imgs"
func read() -> defValues {
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey(cityKey){
print(name)
let valuesToReturn = defValues(defCity: name, loadImgs: true)
return valuesToReturn
}
else {
let valuesToReturn = defValues(defCity: "No default city set", loadImgs: true)
return valuesToReturn
}
}
func write(city: String, load: Bool){
let def = NSUserDefaults.standardUserDefaults()
def.setObject(city, forKey: cityKey)
def.setBool(load, forKey: loadKey)
}
}
in which I have the two functions read, write to read and write data with NSUsersDefault respectively.
On my main ViewController I can read data with:
let loadeddata: defValues = DefaultsSet().read()
if loadeddata.defCityName == "No default city set" {
defaultCity = "London"
}
else {
defaultCity = loadeddata.defCityName
defaultLoad = loadeddata.loadImages
}
But when I try to write data it gives me error. I use this code:
#IBOutlet var settingsTable: UITableView!
#IBOutlet var defaultCityName: UITextField!
#IBOutlet var loadImgs: UISwitch!
var switchState: Bool = true
#IBAction func switchChanged(sender: UISwitch) {
if sender.on{
switchState = true
print(switchState)
}else {
switchState = false
print(switchState)
}
}
#IBAction func saveSettings(sender: UIButton) {
DefaultsSet.write(defaultCityName.text, switchState)
}
You need an instance of the DefaultsSet class
In the view controller add this line on the class level
var setOfDefaults = DefaultsSet()
Then read
let loadeddata = setOfDefaults.read()
and write
setOfDefaults.write(defaultCityName.text, switchState)
The variable name setOfDefaults is on purpose to see the difference.
Or make the functions class functions and the variables static variables and call the functions on the class (without parentheses)
From the code you posted, it seems you either need to make the write method a class method (just prefix it with class) or you need to call it on an instance of DefaultsSet: DefaultsSet().write(defaultCityName.text, switchState).
Another issue I found is that you also need to unwrapp the value of the textField. Your write method takes as parameters a String and a Bool, but the value of defaultCityName.text is an optional, so String?. This results in a compiler error.
You can try something like this:
#IBAction func saveSettings(sender: UIButton) {
guard let text = defaultCityName.text else {
// the text is empty - nothing to save
return
}
DefaultsSet.write(text, switchState)
}
This code should now compile and let you call your method.
Let me know if it helped you solve the problem