How to compare switch case with UIViewController as input in swift 2 - ios

I have some code in older version in swift, like bellow
let initVc:UIViewController? = self.initViewController!
switch initVc {
case let vc as ProductListViewController:
pageMenu?.moveToPage(0)
case let vc as OrderListViewController:
pageMenu?.moveToPage(1)
case let vc as CustomerListViewController:
pageMenu?.moveToPage(2)
default:
pageMenu?.moveToPage(0)
}
in above code self.initViewController is parent view controller from there this controller is pushed.
after updat to swift 2.0 gives and error, like bellow
Immutable value 'vc' was never used; consider replacing with '_' or removing it
Please suggest changes required to fulfil this requirement.

Equivalent code without assigning a value to an (unused) variable
would be:
switch initVc {
case is ProductListViewController:
pageMenu?.moveToPage(0)
case is OrderListViewController:
pageMenu?.moveToPage(1)
case is CustomerListViewController:
pageMenu?.moveToPage(2)
default:
pageMenu?.moveToPage(0)
}
using the "type-casting pattern" is <Type>.

Related

Swift not inferring enum type from other view controller directly

I have declared some enum values in view controller and trying to access in another class, but for some enum I can infer directly but for other I need to use the class name. Sample code
class MyRootViewController: UIViewController {
enum Animation {
case left
case right
case top
case bottom
case none
}
//some code
}
class OtherViewController: UIViewController {
enum Configurations {
case config
case version
case type
}
//some code
}
class Utility {
func addConfiguration(_ config: Configurations) {
//some code
}
func showAnimation(_ animation: MyRootViewController.Animation) {
//Some code
}
}
Here in the second function of Utitlity if I declare like func showAnimation(_ animation: Animation) it throws error "Use of undeclared identifier Animation"
Why did in first method worked even though I didn't mention class but in the second one didn't?
FYI: addConfiguration is giving error.
Please check in your source code, I am sure any framework is having Configurations class or enum is defined in your project.
That's it
please check your first function is not work.
it throws error "Use of undeclared identifier Animation"
so you have change your source code first.
thanks..

handle cases of Enums in Swift

How can we handle the same case with different inputs from the response in Enum's
enum MyNotificationType: String, Codable {
case practice = "push"
case practice = "PracticeRecommendation"
case play = "PlayRecommendation"
case play = "pop"
}
Edit:
I need this because I've common practice image for
push, PracticeRecommendation
and play image for
PlayRecommendation, pop
Edit 2:
enum MyNotificationType: String, Codable {
case push = "push"
case practice = "PracticeRecommendation"
case play = "PlayRecommendation"
case pop = "pop"
}
And added a switch
private func showImage(_ type: MyNotificationType) {
switch type {
case .practiceRecommendation, .push:
self.typeImgView.image = UIImage(named: "Practice")
break
case .play, .pop:
self.typeImgView.image = UIImage(named: "Play")
break
}
}
To deal with Images
Hmm. You can use enums with associated types, though you wouldn't be able to statically ensure possible strings unless you change init(rawType) too. Though, I'm not sure what you are trying to achieve so there could be a different way
enum MyNotificationType{
case practice(value: String)
case play(value: String)
init(rawType: String){
//define what case based on string, do error if you can't handle or use a unknown case
}
}

Swift enum with custom object raw value

I try to implement a state machine for my ViewController, so i create a enum to express the possible state of my ViewController :
enum SMState:RawRepresentable{
case empty,data(UIView),failed(UIView),noData(UIView)
}
The 4 state of enum is suitable for my ViewController, and some state associate with a custom view to show when ViewController enter the specify state.
Then i make SMState impl RawRepresentable Protocol
enum SMState:RawRepresentable{
case empty,data(UIView),failed(UIView),noData(UIView)
typealias RawValue = UIView
init?(rawValue: SMState.RawValue) {
// rawValue is a view but i can't judge what to return
return what???
}
var rawValue: UIView{
switch self {
case .data(let v):
return v
case .failed(let v):
return v
case .noData(let v):
return v
case .empty:
return UIView()
}
}
}
How should i implement init?(rawValue:SMState.RawValue) function above, i can't image how to do this.
Update
Why i implement RawRepresentable :
I think enum is more suitable for representable different state for ViewController instead of Class or Struct, but enum cannot contains stored property, it can only carry a UIView Object through RawRepresentable, any better idea or magic is welcome :D
#Hamish You are right, i shouldn't insist using RawRepresentable, after a nice sleep, i finally archive what i want :
//: Playground - noun: a place where people can play
import UIKit
enum SMState{
case empty,data(UIView),failed(UIView),noData(UIView)
}
extension SMState{
init() {
self = .empty
}
init(failed view:UIView) {
self = .failed(view)
}
init(data view:UIView) {
self = .data(view)
}
init(noData view:UIView) {
self = .noData(view)
}
}
let state = SMState(failed: UIView())
switch state {
case .failed(let v):
print(v)
default:break
}
This is what i want, each enum state own a separate View, i do different operation in different state, using the View that the state carry ~
This approach is much like using Class, in my situation, i am not sure that there may be more states, then it is impossible to extend or subclass the SMState because its a enum, i am think about using Class
What i am trying to do is much like this library StatefulViewController, and i want to make it more flexible.
Any suggestion is welcome ~
:D
There is already available a specific state machine you could use instead of inventing the wheels: GKStateMachine. It has all the required method to transition from state to state. We also use it for different view controller states. Just take you time to read a bit and find some examples, to have your code nice and clean. You will also be able to combine the implementation with a corresponding enum of states, which will just define the states without a need of having associated values there.

Swift custom UITableViewController: switch statement case label section enum

To make my code more readable & maintainable, what's the best way to use labels instead of hardcoded Ints for case labels in a switch statement with a control expression of type Int?
E.g., inside my SettingsTableViewController, I tried
enum Section : Int {
case Phone
case LogOut
case DeleteAccount
}
and in – tableView:didSelectRowAtIndexPath:
switch indexPath.section {
case .Phone:
// Push EditPhoneViewController
case .LogOut:
// Log out
case .DeleteAccount:
// Present action-sheet confirmation
}
but got the compile error
Enum case pattern cannot match values of the non-enum type 'Int'
In the switch you can't simply use indexPath.section as that is not the same type as your enum.
Use switch Section(rawValue: indexPath.section)!

Is it possible to add a case to an existing enumeration where there is no source?

I am implementing my own TableView because I would like to have special animation when reloading a row using reloadRowsAtIndexPaths:withRowAnimation.
The problem is that I need to give a type of animation when I'm calling this method. So I would like to know if it's possible to add an extra case to UITableViewRowAnimation enumeration?
No, it's not possible, for at least one reason: switch statements not using a default case wouldn't compile, because they would be missing the newly added case.
Consider this enum:
enum TestEnum {
case ONE
case TWO
}
and some code using it:
let testOne = TestEnum.ONE
switch testOne {
case .ONE:
println("one")
case .TWO:
println("two")
}
If you were able to add one or more cases in an extension:
extension TestEnum {
case THREE
}
then the switch statement written above wouldn't compile because the new case is not handled.

Resources