Last active
April 22, 2024 07:45
-
-
Save byJeevan/f67485bf380e86d4f87a723ac383827c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SwiftUI Components & Extension that saves iOSDev time. | |
### UIKit is **EVENT-Driven** framework - We could reference each view in the hierarchy, update its appearance when the view is loaded or as a reaction on an event. | |
### SwiftUI is **Declarative, State Driven** framework - We cannot reference any view in the hierarchy, neither can we directly mutate a view as a reaction to an event. | |
Instead, we mutate the state bound to the view. Delegates, target-actions, responder chain, KVO .. replaced with Closures & bindings. |
Click/Tap/Select/Touch event to view:
@State private var isPresented = false
<your view>.gesture(DragGesture(minimumDistance: 0)
.onChanged { value in
if isPresented {
print("Touch down")
}
isPresented = false
}
.onEnded { value in
print("Touch up")
isPresented = true
}
)
.navigationBarHidden(true)
is not constructed for NavigationView
instead, it should be it's child.
Return a view from a function - that checks some conditions.
PS: return types : some View vs AnyView vs View
Ref: https://stackoverflow.com/questions/62895948/how-to-return-a-view-type-from-a-function-in-swift-ui
@ViewBuilder func WidgetDetail(wOption: WidgetOptions) -> some View {
switch wOption.id {
case 0:
CountryPicker()
default:
Text("Widget Not implemented")
}
}
Present view Modally (fullscreen) [ for iOS 14.0+]
@State var isQuizPlayPresented = false
Button(action: {
isQuizPlayPresented.toggle()
}) {
Text("Get Started")
}
.padding()
.fullScreenCover(isPresented: $isQuizPlayPresented, onDismiss: nil, content: QuizPlayView.init)
Dismiss a presented view (modally)
@Environment(\.presentationMode) private var presentationMode // define
self.presentationMode.wrappedValue.dismiss() // In button action
Advanced:
.fullScreenCover(isPresented: $isResultView,
onDismiss: {
self.presentationMode.wrappedValue.dismiss() // Dismisses current view along with Child view dismissed
}, content: {
QuizResultView(totalScore: 10) // Pass custom parameter to child view
})
Make the width of element fill till parent width
VStack(alignment: .center) {
Rectangle()
.frame(height: 0.0) // -------- note this
Text("SHOW DETAILS")
}
.background(.yellow)
Basic Rail :
struct QuizRail: View {
var body: some View {
ScrollView(.horizontal) {
HStack(spacing: 16) {
ForEach((1...10), id: \.self) {_ in
Rectangle()
.frame(width: 150, height: 200)
.cornerRadius(8)
}
}
.padding(.horizontal, 16)
}
}
}
List without separator (from iOS 15.0+)
List {
ForEach(items, id: \.self) { item in
Text("item here")
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
☢️ A workaround calculated the height of ScrollView
@State var heightCalculated = 0.0
var body: some View {
ScrollView {
ForEach(0..<10) { i in
Text("\(i)")
}
.background(
GeometryReader { proxy in
Color.clear.onAppear {
heightCalculated = proxy.size.height
debugPrint(proxy.size.height)
}
}
)
}
.frame(height: heightCalculated)
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tabbar/ TabView creation - VStack as parent.