Even for the app that only enabled Portrait for Device Orientation in General tab.
Make the viewController to be open in landscape override the following properties.
However, it changes the orientation of the presetingViewController. One solution to force the presetingViewController still in portrait is adding the following properties.
Sylvia at Hades Mercury
Tuesday, 3 March 2020
Monday, 3 February 2020
Tuesday, 2 July 2019
Dependency Visualizer
My Fork:
https://github.com/Sylvia-YiyinShen/objc-dependency-visualizer
A dependency visualisation tool for objective-c/Swift project.
Example:
The above graph describe a relation between ViewController and MainViewModel: ViewController just holds a reference of MainViewModel.
If we initialise MainViewModel within ViewController as below, check how different the graph would be:
Other visualisation tools:
https://github.com/Sumolari/swift-relationship-graph
https://github.com/Sylvia-YiyinShen/objc-dependency-visualizer
A dependency visualisation tool for objective-c/Swift project.
Example:
The above graph describe a relation between ViewController and MainViewModel: ViewController just holds a reference of MainViewModel.
If we initialise MainViewModel within ViewController as below, check how different the graph would be:
Other visualisation tools:
https://github.com/Sumolari/swift-relationship-graph
Monday, 10 June 2019
New in Swift iOS 13
Improved Performance
SwiftUI
- 0% Launch time overhead with Swift 5
- 15% Smaller Code Size when using ‘Optimize for Size’
- Faster Bridging Between Swift and Objective-C. Improved string interoperability. 1.6X faster NSDictionary to Dictionary Bridging. 15X faster NSString operations when performed on bridged Swift Strings.
SwiftUI
- Build user interfaces across all Apple platforms
- Improved LocalizedString Interpolation. SwiftUI supports formatted LocalizedString better
Friday, 31 May 2019
String Localization in Xcode
Check example code
https://github.com/Sylvia-YiyinShen/LocalisationExample
Prep work
In Project Info Panel add a language.
Storyboad localization
XCode will prompt to ask you to choose the files/storyboard for localization.
Tap finish, now you should be able to see XCode has generated storyboard.strings for you as below
At the moment it is empty, let's add label in Main.storyboard
And in File Inspector, un-select the language then select again
Now you should see XCode updated the Main.strings file as
Change the labels to another language.
Edit the scheme by
Build and re-run, you should see the translated labels.
XCode provides another way to preview the storyboard
You can change the .strings file to a Interface Build Storyboard
Click the converted .storyboard
XIB Localization
However, you will find other XIB outside of any storyboard has not been localized yet, even those existed before you turn on localization. XCode didn't automatically prepare localization for you and even didn't ask you to choose.
Just select XIB, go to File Inspector, and select the language under Localization section. Similarly, you can choose to convert it to .string or .xib file.
Localize Strings Generated in Code
If you decided to utilize localization at the very beginning, you could create a string file via File -> New -> File
Specify the text in .strings file
Use the localized string
tableName should be the .strings file name
Prepare you strings for Localization
If you don't want localization for now but want to make your strings ready for future requirements.
One day, you want to turn on Localization, select the project, XCode -> Editor -> Export For Localization, XCode will generate a Localizable.strings file contains those strings created via NSLocalizedString(key, comment) along with any other storyboards or XIBs that have been selected localization. Update those exported files, you can choose XCode ->Edit -> Import or just drag the Localizable.strings file into your project.
Drag the file here and link it into XCode, choose the language from Edit Scherme, build and rerun, you should be able to see the transalted texts.
https://github.com/Sylvia-YiyinShen/LocalisationExample
Prep work
In Project Info Panel add a language.
Storyboad localization
XCode will prompt to ask you to choose the files/storyboard for localization.
Tap finish, now you should be able to see XCode has generated storyboard.strings for you as below
At the moment it is empty, let's add label in Main.storyboard
And in File Inspector, un-select the language then select again
Now you should see XCode updated the Main.strings file as
Change the labels to another language.
Edit the scheme by
Build and re-run, you should see the translated labels.
XCode provides another way to preview the storyboard
You can change the .strings file to a Interface Build Storyboard
Click the converted .storyboard
XIB Localization
However, you will find other XIB outside of any storyboard has not been localized yet, even those existed before you turn on localization. XCode didn't automatically prepare localization for you and even didn't ask you to choose.
Just select XIB, go to File Inspector, and select the language under Localization section. Similarly, you can choose to convert it to .string or .xib file.
Localize Strings Generated in Code
If you decided to utilize localization at the very beginning, you could create a string file via File -> New -> File
Specify the text in .strings file
Use the localized string
tableName should be the .strings file name
Prepare you strings for Localization
If you don't want localization for now but want to make your strings ready for future requirements.
One day, you want to turn on Localization, select the project, XCode -> Editor -> Export For Localization, XCode will generate a Localizable.strings file contains those strings created via NSLocalizedString(key, comment) along with any other storyboards or XIBs that have been selected localization. Update those exported files, you can choose XCode ->Edit -> Import or just drag the Localizable.strings file into your project.
Drag the file here and link it into XCode, choose the language from Edit Scherme, build and rerun, you should be able to see the transalted texts.
Sunday, 26 May 2019
Introduction to State Machine for IOS App
Demo:
https://github.com/Sylvia-YiyinShen/StateMachineDemo
Why State Machine pattern? What we want to achieve? What are the benefits introducing State Machine?
1. We want to define rules of transition, final state if needed to end the transitions as well. Un-allowed transitions can be stopped at compiling stage.
2. Since there might be more than one state machines within the whole app, we want to control the existence of state machines(lifecycle of modules).E.g we have SignIn and MainWorkflow state machines, MainWorkflow should not exist until login state has been entered.
Prototyping process
1. For each module, we want to define several states, enum is a good choice.
2. Each state machine is responsible for a single set of states enum, however we hope the state machine class can be reused, so we have to make enums conform to one struct/class.
3. For each state, we want to maintain the allowed transitions which has to be stored property. Since enum does not support store properties, we need a wrapper struct/class of state enum. So we need the help of Generics.
protocol StateIdentifier
class State<T> where T: StateIdentifier
class StateMachine<T> where T: StateIdentifier
In this example, we will have two state sets and accordingly two state machines
enum SignInState: StateIdentifier
enum MainWorkflowState: StateIdentifier
For simplicity, state machines initialisation and configuration are handled in the view controller, ideally we can put in an appCoordinator-like role.
Check configureStateMachine() in ViewController.swift. The configuration requires
1. Initialize the states along with the transition rules
2. Configure state.didEnter .willExit
3. Initialize a state machine with the above states injected
In this simple demo, I am just using a label to indicate where we are at.
Play around the buttons to see how the main workflow module is blocked by sign in/out state.
By introducing state machine, regardless of the messy buggy or wrong routing logic, we will never break the transition rules we've set up.
https://github.com/Sylvia-YiyinShen/StateMachineDemo
Why State Machine pattern? What we want to achieve? What are the benefits introducing State Machine?
1. We want to define rules of transition, final state if needed to end the transitions as well. Un-allowed transitions can be stopped at compiling stage.
2. Since there might be more than one state machines within the whole app, we want to control the existence of state machines(lifecycle of modules).E.g we have SignIn and MainWorkflow state machines, MainWorkflow should not exist until login state has been entered.
Prototyping process
1. For each module, we want to define several states, enum is a good choice.
2. Each state machine is responsible for a single set of states enum, however we hope the state machine class can be reused, so we have to make enums conform to one struct/class.
3. For each state, we want to maintain the allowed transitions which has to be stored property. Since enum does not support store properties, we need a wrapper struct/class of state enum. So we need the help of Generics.
protocol StateIdentifier
class State<T> where T: StateIdentifier
class StateMachine<T> where T: StateIdentifier
In this example, we will have two state sets and accordingly two state machines
enum SignInState: StateIdentifier
enum MainWorkflowState: StateIdentifier
For simplicity, state machines initialisation and configuration are handled in the view controller, ideally we can put in an appCoordinator-like role.
Check configureStateMachine() in ViewController.swift. The configuration requires
1. Initialize the states along with the transition rules
2. Configure state.didEnter .willExit
3. Initialize a state machine with the above states injected
In this simple demo, I am just using a label to indicate where we are at.
Play around the buttons to see how the main workflow module is blocked by sign in/out state.
By introducing state machine, regardless of the messy buggy or wrong routing logic, we will never break the transition rules we've set up.
Saturday, 25 May 2019
Debugging Tricks
Let's look at several debugging tricks, especially helpful when you just joined a team facing with the large and unfamiliar codebase
Quickly find the ViewController that has been pushed along with the line in code.
Go to the Breakpoint Navigator of the left panel in XCode
Click the + button on left bottom, choose Symbolic Breakpoint,
Add the objective-c function signature in Symbol
Disable the breakpoint and enable it just before the interaction triggers pushing that viewController.
XCode will pause the execution at the [UINavigationController pushViewController:animated:] and you will find the exact line in project in Debug Navigator just below [UINavigationController pushViewController:animated:]
Another way to find the name of ViewController or sub UIView/UIViewController
Show the Debug area, build and run, tap the Debug View Hierarchy button on the debug menu bar
Select the view controller or any UI element you want to know and check its name at the top
LLDM commands
po to print
expression to change values at runtime without changing code and re-run
jump to skin without comment out and re-run
Edit breakpoint to put expression in Action
It also allows to continue automatically
Watch values changes, XCode will pause every time the values has been changed
Quickly find the ViewController that has been pushed along with the line in code.
Go to the Breakpoint Navigator of the left panel in XCode
Click the + button on left bottom, choose Symbolic Breakpoint,
Add the objective-c function signature in Symbol
Disable the breakpoint and enable it just before the interaction triggers pushing that viewController.
XCode will pause the execution at the [UINavigationController pushViewController:animated:] and you will find the exact line in project in Debug Navigator just below [UINavigationController pushViewController:animated:]
Another way to find the name of ViewController or sub UIView/UIViewController
Show the Debug area, build and run, tap the Debug View Hierarchy button on the debug menu bar
Select the view controller or any UI element you want to know and check its name at the top
LLDM commands
po to print
expression to change values at runtime without changing code and re-run
jump to skin without comment out and re-run
Edit breakpoint to put expression in Action
It also allows to continue automatically
Watch values changes, XCode will pause every time the values has been changed
Thursday, 16 May 2019
Go Concurrency Patterns
Great materials to go through
https://talks.golang.org/2012/concurrency.slide
https://talks.golang.org/2013/advconc.slide
Check my reorganised code at Github https://github.com/Sylvia-YiyinShen/GolangConcurrency
https://talks.golang.org/2012/concurrency.slide
https://talks.golang.org/2013/advconc.slide
Check my reorganised code at Github https://github.com/Sylvia-YiyinShen/GolangConcurrency
- Channels allows two goroutines to communicate
- Select provides a switch-like way to handle multiple channels instead of multiple goroutines
- time.After to block
- Quit via Select
Pulldown Refresh Demo
Check source code at Github:
https://github.com/Sylvia-YiyinShen/PulldownRefreshDemo
There are several different ways to implement pull-down refresh. One is based on scrollView delegate functions, another one is based on key-value observing on contentOffset. My demo is implemented via the later approach, since when applying the pull-down refreshing to a tableVIew it just requires 2-line changes.
https://github.com/Sylvia-YiyinShen/PulldownRefreshDemo
There are several different ways to implement pull-down refresh. One is based on scrollView delegate functions, another one is based on key-value observing on contentOffset. My demo is implemented via the later approach, since when applying the pull-down refreshing to a tableVIew it just requires 2-line changes.
- Easy to configure refresh control on existing tableView/collectionView
- Easy to replace the indicator(1-line change if using the indicator provided within the demo) https://github.com/Sylvia-YiyinShen/LoadingIndicatorDemo
How to use
- Grab Indicator and PulldownRefresh folder to your project
- Make your tableView subclassing RefreshableTableView
- Invoke RefreshableTableView func configureRefreshControl(refreshHandler: @escaping () -> Void)
- Invoke in the right place RefreshableTableView func refreshDone()
Wednesday, 15 May 2019
Start Learning Golang
Compressed Golang Basics
https://github.com/Sylvia-YiyinShen/GolangBasics
Go Tutorial
https://tour.golang.org
Go Documentation
https://golang.org/doc/
Go Concurrency Model
Go Concurrency Patterns (slides)
Advanced Go Concurrency Patterns (slides)
Share Memory by Communicating
Go Play Space
https://goplay.space/
Install the Go tools
Open and follow the guide
https://golang.org/doc/install?download=go1.12.5.darwin-amd64.pkg
Download .pkg and double click to finish the installation
Then follow the guide to check and test if Go is installed correctly
You can pick any location as the go directory
Test if Go installed correctly
Create a xxx.go file
go build
./xxx
GO extension in VS Code
https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go
https://github.com/Sylvia-YiyinShen/GolangBasics
Go Tutorial
https://tour.golang.org
Go Documentation
https://golang.org/doc/
Go Concurrency Model
Go Concurrency Patterns (slides)
Advanced Go Concurrency Patterns (slides)
Share Memory by Communicating
Go Play Space
https://goplay.space/
Install the Go tools
Open and follow the guide
https://golang.org/doc/install?download=go1.12.5.darwin-amd64.pkg
Download .pkg and double click to finish the installation
Then follow the guide to check and test if Go is installed correctly
You can pick any location as the go directory
Test if Go installed correctly
Create a xxx.go file
go build
./xxx
GO extension in VS Code
https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go
Subscribe to:
Posts (Atom)