#UIStackView
Explore tagged Tumblr posts
y2fear · 1 year ago
Photo
Tumblr media
ios - UIStackView uses the width of the smallest arranged view instead of largest
0 notes
ios-goodies · 5 years ago
Text
Week 363
Happy Thursday! We only have a few more days until the privacy questions on App Store Connect become mandatory on 8 December. And the submissions for the App Store Small Business Program are now open. If you enter before December 18, you can get the benefits from January 1st 2021.
I had been using xcodereleases.com to keep track of the Xcode releases, but I had always found it tricky to figure out which Swift version is used by which Xcode. Well now, with Swift Version from James Dempsey it looks like I won’t have that problem anymore.
Marius Constantinescu
Articles
Swift protocols in SwiftUI, by @zntfdr
Reducing Memory Footprint When Using UIImage, by @Lee_Kah_Seng
UIStackView padding, by @sarunw
How to deal with modal views (a.k.a. sheets) with SwiftUI by @fassko
Testing the UI without UI Testing in Swift by @joemasilotti
What is not so great about SwiftUI, by @tclementdev
Formatted Localizable Strings, by @a_grebenyuk
How to write unit test assertions for Swift Result values, by @mokagio
Adding Views and Modifiers to the Xcode Library, by @kharrison
Tools/Controls
Kanvas: Tumblr’s Media Editor and Camera, by @tumblreng
ColorKit, by @Boris-Em
Business/Career
A Comprehensive Guide to App Pricing Strategies and Tools, by @zachshakked
UI/UX
10 Key Mobile Usability Issues, by @101babich
Credits
zntfdr, LeeKahSeng, pmusolino, sarunw, fassko, Joe Masilotti, Boris-Em
1 note · View note
youngsterdev-blog · 8 years ago
Video
youtube
Introduction to Auto Layout with Xcode (Part-3) - Stack View
0 notes
syndicode · 8 years ago
Text
Pulling off the curtains on new iOS 11
With release of new iOS 11 you could guess that we’ve got new APIs to dig into. So let’s make some reviews and pull off the curtains on new iOS 11.  We will write about just a few additions that caught our eyes while browsing the differences. UIStackView Everyones favorite control received...
0 notes
script-ease · 8 years ago
Link
0 notes
appinessweb · 3 years ago
Text
How to Build a Login Screen in SwiftUI
In WWDC 2019 Apple announced a completely new user interface development framework called SwiftUI. SwiftUI is a user interface toolkit that lets us design apps in a declarative way. There was lots of talk about whether we should use Storyboard or build UI programmatically. SwiftUI is the answer to all these questions. You can now develop the app's UI with a declarative Swift syntax.
No more storyboard, Interface Builder and Auto-layout
Earlier we used to develop user interfaces with storyboards, xib's and auto layout. But with SwiftUI, storyboard and auto-layout are completely out of the picture. Now the code editor is available with a preview canvas.
Migrating from UIKit to SwiftUI
If you've used UIKit before then you need to understand what's the UIKit component equivalent in SwiftUI. Many of the classes you know just by removing prefix UI but few have been renamed. Let's have a look at the list.
1. UIViewController: View
2. UITableViewController: List
3. UITabbarController: TabView
4. UINavigationController: NavigationView
5. UIAlertController: Alert
6. UIAlertController with style .actionSheet: ActionSheet
7. UILabel: Text
8. UITextField: TextField
9. UITextField with secure entry: SecureField
10. UISwitch: Toggle
11. UISlider: Slider
12. UIButton: Button
13. UIStackView with horizontal axis: HStack
14. UIStackView with vertical axis: VStack
15. UIImageView: Image
16. UISegmentedControl: SegmentedControl
17. UIStepper: Stepper
18. UIDatePicker: DatePicker
19. UIPickerView: Picker
20. UITabbar: TabView
21. UINavigationBar: NavigationView
22. UIScrollView: ScrollView
Creating Project:
Step 1 - Creating a new project with SwiftUI
Step 2 - Add the VStack in the View. It will act as Vertical StackView
Step 3 - Add title text as Login in the View and can set style to the Text.
Step 4 - Adding Image to the top of the Screen to show that its user's login and adding frame of width and height as shown below.
Fig 1 - Adding Image and Text
Step 5 - Adding Text Field for Phone Number and password with TestField and SecureField inside the VStack and Alignment to leading.
Step 6 - Adding placeholder to the textfield , Add Text and Value will be saved in the Variable.
Step 7 - Give Divider() for allowing space between two textfield and add style as required for the textfield to be displayed.
Step 8 - Adding padding to bottom and given 15.
Step 9 - Adding Button of forgot password inside the HStack to align the right corner of the screen with the Text as shown below.
Fig 2 - Adding Textfield and SecureField with Forget Password
Step 10 - Add a button with the title “Login” for clicking the login functionality inside the VStack.
Step 11 - In this button Action will be added inside the action closure function and can add text to the button (i.e Title) and Style the button as shown.
Fig 3 - Adding Button with Action and Text
Step 12 - Add a button which will have an action to move to SignUp Screen inside the HStack with spacing. Where the SignUp text will be clickable which we implement using Attribute text Similarly in SwiftUI it is implemented in Simple Way.
Fig 4 - "Don't have an Account ? Sign Up"
Final Result - Login Screen with PhoneNumber and Password using SwiftUI
Conclusion
SwiftUI is new to everyone and might take time to get stable as a framework. But SwiftUI is the future of iOS development. There are a lot of things to learn in SwiftUI.
0 notes
ramiresmoreira · 5 years ago
Link
0 notes
dotomtom · 5 years ago
Photo
Tumblr media
最近の弊社のiOS開発はUIStackViewとUIViewControllerでできたコンポーネントをフル活用してこんな感じにUIを書けるようになってます!宣言的UIまでは程遠いがコンポーネントの再利用で無駄のないUI開発に近いてる(気がする) https://t.co/49Trqvwg4r yuzushioh さんのツイートから
0 notes
jack-magnus · 6 years ago
Video
tumblr
UIStackView Tutorial - Programmatic - Xcode 11 https://www.youtube.com/watch?v=_DADWRicrGU
0 notes
fitnesshealthyoga-blog · 6 years ago
Photo
Tumblr media
New Post has been published on https://fitnesshealthyoga.com/refactoring-with-uistackview/
Refactoring with UIStackView
Written by Nicholas Steppan Meschke, Software Engineer iOS
What awaits you
As developers who care about the user experience of our app, we’ll likely encounter some scenarios that require a view to reflect different states. Sometimes, the state of the view may even impact its size. The code that handles all those transitions can quickly become a mess. In this article, we want to share our approach to implementing such scenarios using UIStackView.
Let’s start with an example
We use a simple app idea to demonstrate how we can achieve that. We already have a demo app that has a simple button, which increases a counter when tapped. The number of taps is displayed on the screen. To make the demo app more interesting, we’ll add functionality to set and track tapping goals!
We can now set goals! Here’s the code that’s responsible for setting up the constraints for the empty tapping goal view.
private func setupEmptyGoal()   // … code left out   NSLayoutConstraint   .activate([emptyGoalTitleLabel.topAnchor.constraint(equalTo: emptyGoalView.topAnchor, constant: 16),     emptyGoalTitleLabel.trailingAnchor.constraint(equalTo: emptyGoalView.trailingAnchor, constant: -16),     emptyGoalTitleLabel.leadingAnchor.constraint(equalTo: emptyGoalView.leadingAnchor, constant: 16)])   NSLayoutConstraint   .activate([optionsStackView.topAnchor.constraint(equalTo: emptyGoalTitleLabel.bottomAnchor, constant: 32),     optionsStackView.trailingAnchor.constraint(equalTo: emptyGoalView.trailingAnchor, constant: -16),     optionsStackView.leadingAnchor.constraint(equalTo: emptyGoalView.leadingAnchor, constant: 16),     optionsStackView.bottomAnchor.constraint(equalTo: emptyGoalView.bottomAnchor, constant: -16)])   NSLayoutConstraint   .activate([emptyGoalView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),     emptyGoalView.bottomAnchor.constraint(equalTo: bottomAnchor),     emptyGoalView.trailingAnchor.constraint(equalTo: trailingAnchor),     emptyGoalView.leadingAnchor.constraint(equalTo: leadingAnchor)])
The code sets the constraints for the view in the EmptyGoal state. Cool, we now have the state where we don’t have a goal, so let’s create one for when a goal is set.
Here’s the code responsible for creating and setting up view for when we have a goal set. Let’s call this state GoalSet.
private func setupGoalView()   // … code left out   NSLayoutConstraint   .activate([goalTitleLabel.topAnchor.constraint(equalTo: goalView.topAnchor, constant: 16),     goalTitleLabel.centerXAnchor.constraint(equalTo: goalView.centerXAnchor)])   NSLayoutConstraint   .activate([progressLabel.topAnchor.constraint(equalTo: goalTitleLabel.bottomAnchor, constant: 16),     progressLabel.centerXAnchor.constraint(equalTo: goalView.centerXAnchor),     progressLabel.bottomAnchor.constraint(equalTo: goalView.bottomAnchor, constant: -16)])   NSLayoutConstraint   .activate([goalView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),     goalView.topAnchor.constraint(equalTo: goalSetLabel.bottomAnchor, constant: 16),     goalView.bottomAnchor.constraint(equalTo: bottomAnchor),     goalView.trailingAnchor.constraint(equalTo: trailingAnchor),     goalView.leadingAnchor.constraint(equalTo: leadingAnchor)])
Awesome, now we can set a tapping goal and track it in our app. However, there’s one issue here: even though the spacing in our view in the GoalSet state should be 16pt, it appears to be a lot more. That’s weird, but let’s keep improving our app by introducing a Success state, for when we achieve our goal!
Here’s our Success state view and below, the code for it:
private func setupSuccessView()   // … code left out   NSLayoutConstraint   .activate([imageView.topAnchor.constraint(equalTo: successView.topAnchor),     imageView.bottomAnchor.constraint(equalTo: successView.bottomAnchor),     imageView.trailingAnchor.constraint(equalTo: successView.trailingAnchor),     imageView.leadingAnchor.constraint(equalTo: successView.leadingAnchor)])   NSLayoutConstraint   .activate([successView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),     successView.topAnchor.constraint(equalTo: goalSetLabel.bottomAnchor, constant: 16),     successView.bottomAnchor.constraint(equalTo: bottomAnchor),     successView.trailingAnchor.constraint(equalTo: trailingAnchor),     successView.leadingAnchor.constraint(equalTo: leadingAnchor)])
But what’s wrong?
Yay, now we have our 3 state views for our clicking goal app! But when we open our app, it looks like this:
Apart from looking really strange and stretched, we have a bunch of constraints that basically do the same thing: constrain the state views to our superView. How can we improve that?
UIStackView to the rescue!
UIStackViews are a really useful tool for laying out a collection of views in either column or row. In our case, we are going to use the UIStackView to group our state views, and it will adapt its size according to what is inside it. Our new code looks like this:
private func setupStackView()   // … code left out   NSLayoutConstraint   .activate([stackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),     stackView.trailingAnchor.constraint(equalTo: trailingAnchor),     stackView.leadingAnchor.constraint(equalTo: leadingAnchor),     stackView.bottomAnchor.constraint(equalTo: bottomAnchor)]) private func setupSuccessView()   // … code left out   NSLayoutConstraint   .activate([imageView.topAnchor.constraint(equalTo: successView.topAnchor),     imageView.bottomAnchor.constraint(equalTo: successView.bottomAnchor),     imageView.trailingAnchor.constraint(equalTo: successView.trailingAnchor),     imageView.leadingAnchor.constraint(equalTo: successView.leadingAnchor)]) private func setupGoalView()   // … code left out   NSLayoutConstraint   .activate([goalTitleLabel.topAnchor.constraint(equalTo: goalView.topAnchor, constant: 16),     goalTitleLabel.centerXAnchor.constraint(equalTo: goalView.centerXAnchor)])   NSLayoutConstraint   .activate([progressLabel.topAnchor.constraint(equalTo: goalTitleLabel.bottomAnchor, constant: 16),     progressLabel.centerXAnchor.constraint(equalTo: goalView.centerXAnchor),     progressLabel.bottomAnchor.constraint(equalTo: goalView.bottomAnchor, constant: -16)]) private func setupEmptyGoal()   // … code left out   NSLayoutConstraint   .activate([emptyGoalTitleLabel.topAnchor.constraint(equalTo: emptyGoalView.topAnchor, constant: 16),     emptyGoalTitleLabel.trailingAnchor.constraint(equalTo: emptyGoalView.trailingAnchor, constant: -16),     emptyGoalTitleLabel.leadingAnchor.constraint(equalTo: emptyGoalView.leadingAnchor, constant: 16)])   NSLayoutConstraint   .activate([optionsStackView.topAnchor.constraint(equalTo: emptyGoalTitleLabel.bottomAnchor, constant: 32),     optionsStackView.trailingAnchor.constraint(equalTo: emptyGoalView.trailingAnchor, constant: -16),     optionsStackView.leadingAnchor.constraint(equalTo: emptyGoalView.leadingAnchor, constant: 16),     optionsStackView.bottomAnchor.constraint(equalTo: emptyGoalView.bottomAnchor, constant: -16)])
The layouts are now being shown according to their respective constraints, and our code looks simpler and easier to understand. By using the UIStackView, we swapped 3 addSubview calls for 1, and 12 layout constraints for only 4.
Wait, that’s not all!
Right now, we manage our states through 3 methods and to set our view state to the desired state, we need to call all of them, which looks something like this:
showGoal(false) showEmptyGoal(false) showSuccessView(true)
That’s not optimal for maintainability, and understanding the code could obviously be easier. To fix this, we can introduce a new Enum with values that represent our states. Our code should look like this:
enum GoalViewState     case empty, goal(value: GoalSize), success enum GoalSize: Int     case small = 15, medium = 45, big = 100          var text: String         return String(self.rawValue)     
Inside our view, we create a new property “state” of type GoalViewState. It’s responsible for storing and handling our state changes using didSet method. The resulting code looks like this:
var state: GoalViewState = .empty     didSet         updateState(with: state)      private func updateState(with state: GoalViewState)     stackView.arrangedSubviews.forEach $0.isHidden = true     goalSetLabel.isHidden = true              switch state     case .empty:         emptyGoalView.isHidden = false     case .goal(let value):         goalView.isHidden = false         goalSetLabel.isHidden = false         setGoal(value)     case .success:         successView.isHidden = false     
Ok, but what does it do and how does it work? Simple! If we need to change the state of our view, we can call “state = .goal(.small)”, making the code more readable and less error-prone, giving whoever reads it a better idea of what’s going on.
Wrapping up
UIStackViews are a quite powerful tool, but like other tools, they are not a silver bullet for every problem. Our constraint problem could have been fixed using a height constraint in the superview, however, that would require us to manually calculate the view size, which would make maintenance more difficult later on. Using a UIStackView, the size is inferred using its contents. This not only gives us a convenient way to have our views correctly sized, but also is robust enough to deal with other requirements, such as showing two states at once. That’s it for today!
Have you ever used a UIStackView as we described in this article? Let us know in the comment section below!
***
//check Cookie Opt out and User consent if(!getCookie("tp-opt-out")) !function(f,b,e,v,n,t,s)if(f.fbq)return;n=f.fbq=function()n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments);if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)(window, document,'script','https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '1594940627485550'); // Insert your pixel ID here. fbq('track', 'PageView');
Source link
0 notes
toasty323 · 6 years ago
Text
Solutions to Address Uiscrollview Optimization Problems
Tumblr media
Shaded shadows: shadows rendering for UIView Using shadows in the drawing area, you can create a 3D effect that highlights certain elements. This approach is well known and very popular. In most cases, using the default method for adding shadows to objects in the cell will not cause any problems. However, when the cell and the UIScrollView suboviews become overloaded, such an approach reduces the fluidity of scrolling. The problem is that the shadow is calculated using the value of the alpha channel of each pixel of a given UIView, which reduces the rendering of frames per second (FPS). For more information contact with
Mobile App Developer in Austin
. Solution: use shadowPath To avoid these problems, you must use shadowPath when adding the shadow. In this way, you can make the shadow using a specific shape and gradient, which is significantly faster than the pixel-by-pixel calculation process. Views that fail when hiding: rendering shadows for UIView (hidden version) The next performance problem of UIScrollView occurred during the test on the iPhone 6 Plus / 6s Plus / 7 Plus, where the scrolling was reduced. The main animation tool has confirmed a decrease in the refresh rate (FPS) from averages of 55 to 35 on screens with problems displaying the content. When looking for a solution, the team found that the problem was known to these devices and that it was possible to disable transparency in iOS settings. Solution 1: Turn off the shadows The first solution is to disable shadows when UIView is not visible by setting a value of 0 for the shadowOpacity parameter. Although this solution is the simplest and most convenient option if you have a clear visual control system, it is not very versatile. Solution 2: Use shadowPath The second option is to use shadowPath for shadow, which makes rendering much easier. Further requirements can be found in the responsiveness of UIView, animation, and other processes associated with coordinate transformation because it is necessary to support UIBezierPath changes. Content scrolling selection of content: including UIScrollView and UITableView Another task that we encountered and solved during this project was to implement embedded UIScrollView to create a navigation similar to that used in Media, Twitter and IMDb. We had to create a header with general information, a tabbed panel with variable tabs (fixed at the top of the screen while scrolling) and an area with a horizontal UIScrollView containing pages in the form of vertical tables. Solution: use the container The solution to this problem is described in detail in an article by Daniele Margutti entitled "Efficient Scrolling of UIStackView in Swift". The main task of the article is to perform these steps: Implement a delegate of the main UIScrollView function, in particular the scrollViewDidScroll (_ scrollView: UIScrollView) method. Places visible content in views that are containers. Containers must have a FrameSize equal to the size of the content. This allows you to calculate the correct offset size and value of the UIScrollView main view. Calculates the visible portion of the table after each change in the parent UIScrollView offset. Keep the table size of the table less than or equal to the size of the device display. Change frame.origin and contentOffset of the internal UIScrollView to move the visible part and adjust it to the visible part of the parent UIScrollView. Conclusion: the warning is ready Although UIScrollView and UITableView have relatively simple and understandable functional principles, optimization problems are still evident. They can also occur in the case of small deviations in the use of standard component flow.
0 notes
ios-goodies · 5 years ago
Text
Week 336
Happy Thursday! It’s been a quiet week, people are getting excited and impatient for WWDC, and even WWDC-related social events are moving online.
Marius Constantinescu
Articles
Scroll List to Row in SwiftUI, by @lostmoa_nz
Things we Wish we Knew about iOS Voice Over, by @ExyteHQ
Embracing the Dynamic Type, by @fassko
Responsive design with UIStackView, by @sarunw
Mastering images in SwiftUI, by @mecid
MVI Architecture for SwiftUI Apps, by @AnupAmmanavar
How the SwiftUI DSL Works, by @_HarshilShah
Getting the most out of Xcode Previews for SwiftUI, by @johnsundell
Dealing with memory limits in iOS app extensions, by @igorkulman
An In-Depth Look at Blur Effect Materials on iOS, by @nish_desai
Lessons learned implementing Sign in with Apple on iOS, by @andrea_anto97
Llbuild2, by @daniel_dunbar
Videos
Accessibility for iOS: doing well by doing good, by @djembe
Credits
nataliapanferova, ExyteHQ, fassko, sarunw, mecid, AnupAmmanavar
1 note · View note
learnswiftorxamarin · 8 years ago
Text
StatusBarにViewが被らないようにする(コードでなんとかする)
NavigtationControllerを使わない場合、ViewがStatus Barにかぶる。 この対策の1つにStatus Bar分の高さを考慮してViewを作る方法がある。
var offset = UIApplication.SharedApplication.StatusBarFrame.Height; var rect = View.Bounds; rect.Y = rect.Y + offset; rect.Height = rect.Height - offset; var stack = new UIStackView(); stack.Frame = frame;
0 notes
fbreschi · 5 years ago
Text
Hidden gems of UIStackView
http://bit.ly/2uhvmuU
0 notes
myrtlecornish · 6 years ago
Text
A Brief Tour of Swift UI
The best user interfaces are interactive and responsive to the user. UIKit is a capable framework that lets you build apps that users expect, but it can be tedious at time, not to mention having the flavor of an Objective-C toolkit.
SwiftUI takes advantage of Swift’s modern language features, giving us a modern framework that hits modern programming buzzwords.
It’s Declarative. Describe your UI in broad strokes using simple code.
It’s Compositional. You take existing views and connect them together and arrange them on the screen as you want.
It’s Automatic. Complex operations, like animations, can be done as a one-liner.
It’s Consistent. SwiftUI can be run on all of Apple’s platforms. It will take care to configure your UI (such as padding distance between on-screen controls, or dynamic type) so that it feels at home on whatever platform it’s running, whether it’s a Mac or the AppleTV.
Views and View Modifiers
Views are the heart of SwiftUI. According to Apple:
Views are defined declaratively as a function of their input
A View in SwiftUI is a struct that conforms to the View protocol. They are unrelated to UIViews (which are classes). A SwiftUI View is a value type, composed of the data that explains what you want to display.
Here’s a simple view:
struct Simpleiew : View { var body: some View { Text("I seem to be a verb") } }
Here SimpleView conforms to the View protocol. To appease the protocol, you need to provide a body, which is an opaque type. By using some new syntax, some View, we’re declaring that body is some kind of View, without having to specify a concrete type. Check out Swift Evolution Proposal 244 for more about opaque types.
The body is some View that describes what should be on the screen. In this case it’s a simple text label with a default configuration. Your body can be composed of multiple Views, such as a stack that arranges images horizontally.
Because body is a View, and it’s an opaque type, nobody really cares if a given View ends up being a single on-screen entity or a bunch of views composed in a stack or a list. This lets us compose complex hierarchies easily.
Chain Reaction
SwiftUI Views are value types, so we really don’t have stored properties to modify their look and feel. We need to declare our look and feel intentions to customize our views.
SwiftUI has ViewModifiers, such as .foreground to change the foreground color or .font to change a view’s font, that applies an attribute to a View. These modifiers also return the view they’re modifying, so you can chain them:
Text("SwiftUI is Great!") .foreground(.white) .padding() .background(Color.red)
This declarative syntax is very easy to read, letting you accomplish a lot with little code.
Stacks
You can build hierarchies of views. In UIKit, we use UIStackView to make vertical and horizontal stacks of UIViews. In SwiftUI, there’s an analogous HStack and VStack views that let you pile views horizontally or vertically.
This view positions one label above another.
VStack { Text("Swift UI is Great!") .foreground(.white) .padding() .background(Color.red) Text("I seem to be a verb") }
There’s also ZStack that lets you stack views on top of each other, like putting a label on top of an image.
You’re welcome to nest multiple stacks to compose complex view hierarchies. The stack views will automatically provide platform-appropriate defaults and if you don’t like the defaults, you can provide your own alignment and spacing.
Lists
SwiftUI lists look like tableviews in UIKit. In SwiftUI, the framework does the heavy lifting, freeing you from data source boilerplate.
Setting up a list with hard-coded views is really easy. Setting it up is exactly like setting up a stack:
struct ListView : View { var body: some View { List { Text("Look") Text("A") Text("TableView") } } }
The views inside the closure of a list serve as static cells.
The List also has an optional data parameter (that conforms to the Identifiable protocol) where you can provide some data to drive the creation of the cells inside the table.
Here’s a struct of a contact:
struct Contact: Identifiable { let id = UUID() let name: String }
Having a unique identifier in your identifiable data helps with list selection and cell manipulation.
And here’s a View that hardcodes a list of contacts:
struct ListView : View { let contacts = [Contact(name: "Arya"), Contact(name: "Bran"), Contact(name: "Jon"), Contact(name: "Sansa")] var body: some View { List(contacts) { contact in Text(contact.name) } } }
This is the magic bit:
List(contacts) { contact in Text(contact.name) }
This is telling the list: “for every Identifiable in this list of contacts, make a new Text view whose text contents are the contact’s name. You can add new folks to contacts, and the list will contain more rows.
State and Binding
Static hard-coded lists are great for initial prototyping of your ideas, but it’d be nice for the list to be dynamic, such as populating it with data from the internet. Or insert and delete new rows, and to rearrange things.
WWDC 2019 session 226 Data Flow Through SwiftUI tells us:
In SwiftUI data is a first class citizen
To manage state within our app, SwiftUI provides stateful binding to data and controls using property wrappers. Check out Swift Evolution Proposal 258 for more about property wrappers.
Here we’re using the the @State property wrapper to bind an isEnabled property to a toggle control:
struct EnabledTogglingView : View { @State private var isEnabled: Bool = false var body: some View { Toggle(isOn: $isEnabled) { Text("Enabled") } } }
Another quote from session 226, Data Flow Through SwiftUI:
SwiftUI manages the storage of any property you declare as a state. When the state value changes, the view invalidates its appearance and recomputes the body.
The state becomes the source of truth for a given view.
@State is great for prototyping, and for properties that are intrinsic to a view (such as this enabled state). To actually separate your data layer from your view layer, you need BindableObject.
So say we’re setting up a preference panel, or some kind of configuration panel with a sequence of toggle buttons. First, a model object for each individual setting:
class Settings: BindableObject { var didChange = PassthroughSubject<Bool, Never>() var isEnabled = false { didSet { didChange.send(self.isEnabled) } } }
Notice that Settings is a reference type (a class), which conforms to the BindableObject protocol. The PassthroughSubject doesn’t maintain any state - just passes through provided values. When a subscriber is connected and requests data, it will not receive any values until a .send() call is invoked.
struct BindableToggleView : View { @ObjectBinding var settings: Settings var body: some View { Toggle(isOn: $settings.isEnabled) { Text("Enabled") } } }
take another look at this line of code:
@ObjectBinding var settings: Settings
That’s weird. It’s not an optional then what’s it initialized to? Well, because settings is declared with the @ObjectBinding property wrapper, this tells the framework that it will be receiving data from some bindable object outside of the view. This object binding doesn’t need to be initialized.
You inject a BindableObject into the View that should use it. Here’s how our Settings gets hooked up to this BindableToggleView:
BindableToggleView(settings: Settings())
Your view does not care where the data lives or how it is populated disk, cache, network, osmosis. The view simply knows that it will be binding to some object when available.
The @ObjectBinding property wrapper creates a two-way binding. Whenever a mutation occurs the view automatically re-renders.
@ObjectBinding requires dependency injection to provide the data object. That can be inconvenient.
To make this object available anywhere within your app without dependency injection you can use the environment. New with SwiftUI you have an environment object that contains all kinds of information like screen size, orientation, locale, date format, etc. If you stick an object into the environment then that object can be accessed anywhere within your app. Think of it as a dictionary that is globally scoped within your app.
So how do you use it? The @EnvironmentObject property can help you with this.
struct BindableToggleView : View { @EnvironmentObject var settings: Settings var body: some View { Toggle(isOn: $settings.isEnabled) { Text("Enabled") } } }
In the above example, everything remains the same as seen previously, except you replace @ObjectBinding with @EnvironmentObject.
To inject an object into the environment you call the .environmentObject method.
ContentView().environmentObject(Settings())
An instance of Settings is now injected into the environment and is available to you anywhere within your app. When the object mutates then every view bound to it will receive the update and re-render its view. You no longer have to maintain a mental model of all the dependency-injections to keep your user interface in sync.
Animation
Animations in SwiftUI work like any view modifier. Basic animations can be achieved using the withAnimation method.
Here’s a View with two text labels:
struct ContentView: View { @State var scale: CGFloat = 1 var body: some View { VStack { Text("This text grows and shrinks") .scaleEffect(scale) Text("Scale it") .tapAction { self.scale = self.scale == 1.0 ? 5.0 : 1.0 } } } }
Tapping the second text label alters the size of the first text label, alternating its size between normal and five-times larger. The scaling happens instantly without any animation.
It’s a one-liner to make it animate smoothly.
Text("Scale it") .tapAction { withAnimation { self.scale = self.scale == 1.0 ? 5.0 : 1.0 } }
withAnimation can take an argument that lets you customize the animation. You can call it with a .basic animation, or you can have more fun with .spring animation that gives you control to make a beautiful spring effect.
Conclusion
SwiftUI is a delight to use. The focus is on creating an app because SwiftUI gets out of your way, taking care of a lot of annoying details. Design rich, interactive user interfaces by composing reusable views. Ensure data is coming into the system and not worry about keeping the view and model layers in sync. Finally, easily add animations to make views come alive.
A Brief Tour of Swift UI published first on https://johnellrod.weebly.com/
0 notes
cdemiranda · 6 years ago
Link
via Ray Wenderlich
0 notes