Is SwiftUI build on top of UIKit? - swiftui

i can't explain why extension on UIKit's UIPickerView affects on SwiftUI's picker.
and does that mean that knowing basics of uikit is very useful for learning swiftui?
does it even make sense to learn swiftUI if it's basically UIkit library(if I am right)
extension UIPickerView {
open override var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric, height: 200)
}
}
GeometryReader { geometry in
HStack(spacing: 0) {
Picker(selection: self.$daySelection, label: Text("")) {
ForEach(0 ..< self.days.count) { index in
Text("\(self.days[index]) d").tag(index)
}
}
.pickerStyle(.wheel)
Picker(selection: self.$daySelection, label: Text("")) {
ForEach(0 ..< self.days.count) { index in
Text("\(self.days[index]) d").tag(index)
}
}
.pickerStyle(.wheel)
Picker(selection: self.$daySelection, label: Text("")) {
ForEach(0 ..< self.days.count) { index in
Text("\(self.days[index]) d").tag(index)
}
}
.pickerStyle(.wheel)
This extension solves problem of overlapping gesture areas of pickers in ios 15.

Is SwiftUI built on top of UIKit?
No... and yes, sometimes.
There are controls in SwiftUI that do reach into UIKit to use those. Although, not all of them.
And as Vacawama rightly pointed out… if running on MacOS then AppKit also.
The thing about SwiftUI is to not worry too much about the underlying technology. It may be that Apple chooses to significantly rewrite the foundation of it. Perhaps taking a previously used UIKit component and writing it natively in SwiftUI. But the SwiftUI code shouldn’t change.
Is SwiftUI a UIKit library?
No, absolutely not. They are fundamentally different ways of thinking about and creating UI.
Does it make sense to learn SwiftUI?
Yes, it makes sense to learn SwiftUI AND UIKit. Also, Combine and CoreGraphics and GameKit... Do you want to be an iOS developer or a SwiftUI developer?
Random bit of badly indented code...
I'm not sure what this is doing in your question.

Related

Swiftui navigationBarTitle beging overwritten with Preview View Text

When I go to my second page which has a ScrollView, and I scroll to the point it becomes inline and then return to the mainView - the navigationBarTitles is being overwritten with both navigationBarTitles.
I am using Xcode Version 12.5 (12E262) and this is iOS 14.
It is happening both in the simulator and on a device.
MainView
ScrollView
ScrollView scrolled so it becomes inline
And when I return to the MainView from the inline NavBar I get this.
It is fine - unless I have scrolled. And what makes it even more confusing it only does it about 25% of the time.
I am just using "self.presentationMode.wrappedValue.dismiss()" to return to the mainView
I am using a NavigationLink to go to the second page.
NavigationLink(destination: ScrollView(), isActive: $showScroll ) { EmptyView() }
Is there something I have missed when dismissing from Scrolling?
very plain code for the scrollView.
I am obviously missing something or this is a big issue with SwiftUI and Xcode.
Thank you.
var body: some View {
ScrollView(showsIndicators: false) {
}
.navigationBarBackButtonHidden(true)
.navigationBarTitle("scrollView Page")
.navigationBarItems(
leading:
Button(action:{
self.presentationMode.wrappedValue.dismiss()},
label: {
Image(systemName: "arrow.left")
})
}

SwiftUI TabView Animation Not giving any animation

I'm trying to create a TabView Slider in SwiftUI with 3 modals that will onboard a user. The default PageTabViewStyle() is a little basic and I'm wanting it to animate with the default slide speed etc.
I've tried appending animation along with the transition from what I've seen online including StackOverflow but it doesn't work.
Here's what I currently have:
ZStack {
Color.black
TabView(selection: $currentTab) {
ForEach(OnboardingData.list) { viewData in
OnboardingModal(data: viewData)
.tag(viewData.id)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.animation(.easeInOut)
.transition(.slide)
}

How do I prevent SwiftUI's TabView from moving vertically when dragging? [duplicate]

I have set up a TabView in my application, so that I can swipe horizontally between multiple pages, but I also have an unwanted vertical scroll that may appear, with a bounce effect so. How can I disable this vertical scroll?
My code:
struct ContentView: View {
#State private var currentTabIndex: Double = 0
var body: some View {
VStack {
TabView(selection: $currentTabIndex) {
Text("Text n°1")
.tag(0)
Text("Text n°2")
.tag(1)
}
.border(Color.black)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
}
I had this same problem. It's not an exact solution, but you can turn off bouncing on scrollviews (which is used within a TabView). And as long as the items within the TabView are not larger than the TabView frame, it should act as if you disabled vertical scrolling.
I would call it either .onAppear or in your init function:
.onAppear(perform: {
UIScrollView.appearance().bounces = false
})
Note: this disables the bouncing on ALL scrollviews across your app... So you may want to re-enable it .onDisappear.
Still an issue with Xcode 12.4.
I managed to workaround that by wrapping the TabView within a ScrollView and using the alwaysBounceVertical property set to false, as follow:
ScrollView(.horizontal) {
TabView {
///your content goes here
}
.tabViewStyle(PageTabViewStyle())
}
.onAppear(perform: {
UIScrollView.appearance().alwaysBounceVertical = false
})
.onDisappear(perform: {
UIScrollView.appearance().alwaysBounceVertical = true
})
I actually came across this because I saw this effect in a tutorial but couldn’t replicate it on iOS 15.2. However, I managed to replicate it on iOS 14.4 on another simulator side by side. So I guess this behaviour is disabled or fundamentally changed in the newer iOS.
Demonstration

Use LazyVStack in SwiftUI 1

One of the new features of SwiftUI 2 are LazyVStacks. Is it possible to implement its functionality in the current SwiftUI framework? I have the following code sample where I want to use it:
var body : some View {
VStack(alignment: .leading){
ScrollView {
Text("sample")
VStack{ // I want to have a LazyVStack here
ForEach(1..<10000, id: \.self) {_ in
Text("test")
}
}
}
}
}
Normally i would use a List which is by default lazy. But due to other constraints it's not possible.
Thanks in advance.
You have to install Xcode 12 beta in order to use LazyStacks. If you are coding for an iOS app, the simulator will run correctly, but if you are coding for a macOS app you will have to update to Big Sur also in order to run the SwiftUI 2 code.

Set navigation bar item style in SwiftUI

When adding a navigation bar item with UIKit, you set its style with UIBarButtonItem.style. This is important for a Done button, which is displayed with bold text.
SwitftUI's navigationBarItems(leading:trailing:) takes a View but no style. You could hack a style look-alike by using a bold button in the view, but it won't adjust to future OS style changes (e.g. a font weight other than bold).
How do you set the navigation bar item's style with SwiftUI?
iOS 14+
It is worth noting that using ToolbarItem(placement:) within a toolbar modifier will automatically apply emboldened text to buttons in the .confirmationAction placement position.
For example:
struct MyView: View {
var body: some View {
NavigationView {
Form {
// other elements
}
.navigationTitle("Edit Publication")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") { }
}
ToolbarItem(placement: .confirmationAction) {
Button("Save") { }
}
}
}
}
As you can see from the illustration below, the Save button appears in bold.
If you want a button in the same place as the Save button below but not to be emphasised, you'd use the .primaryAction modifier.
Using the placement types that describe toolbar items' context – rather than using the deprecated navigationBarItems modifier, or the .navigationBarTrailing and .navigationBarLeading placement values – is the best way to make your SwiftUI views adapt to any changes in future versions of iOS.
They're also applicable across multiple platforms that don't necessarily have navigation bars, and other platforms may choose to render them differently. For example, using .confirmationAction on macOS creates a button with the app accentColor as a background.
I think we have to change how we think about SwiftUI as the concepts of "UIBarButtonItem.style" won't be directly applicable. SwiftUI tries to hide implementation details and wants concepts like changing the font-weight to "auto-magically work" depending on the context.
On Xcode 12.3, and iOS 14.3, seems that by default the button styles are bold (in the context of NavigationView):
.navigationBarItems(
leading:
Button(action: {}) {
Text("Cancel")
},
trailing:
Button(action: {}) {
Text("Save")
}
)
One way to change styling is by adding a button style:
.navigationBarItems(
leading:
Button(action: {}) {
Text("Cancel")
}.buttonStyle(PlainButtonStyle()),
trailing:
Button(action: {}) {
Text("Save")
}
)
But that did not achieve the desired effect. I had to change the font weight to have the "Cancel" be a regular style, and "Save" be bold...just like standard iOS:
.navigationBarItems(
leading:
Button(action: {}) {
Text("Cancel")
.fontWeight(Font.Weight.regular)
},
trailing:
Button(action: {}) {
Text("Save")
}
)
The nice thing about this is that you don't need to know about the concept of "UIBarButtonItem.style:" you just need to know about the concepts of what a Button is, and what Text is - which API should be familiar over-time as they are standard building blocks.
in SwiftUI instead of passing a style you append it to the View component. this will adjust to future OS style changes:
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
var body: some View{
NavigationView {
Text("blah")
.navigationBarItems(leading: Text("done button")
.fontWeight(.medium)
.bold()
.foregroundColor(Color.red))
}
}
}
PlaygroundPage.current.setLiveView(ContentView())