How do I change scrollview's scroll direction in SwiftUI? - swiftui

I was trying to implement vertical scroll with image and text but I am not able to achieve it.
I tried on both Xcode beta 1 & 2.

Try to wrap both the Text and the Image in a VStack and be sure that there is enough content inside the ScrollView to fall outside it's bounds (in the right direction - vertically in your case):
ScrollView {
VStack {
ForEach (1...100) {_ in
Image(systemName: "circle.fill")
Text("my text")
}
}
}
You could easily try it out in a Playground like this :
import SwiftUI
import PlaygroundSupport
struct LiveView : View {
var body: some View {
ScrollView {
VStack {
ForEach (1...100) {_ in
Image(systemName: "circle.fill")
Text("Some text")
}
}
}
}
}
PlaygroundPage.current.liveView = UIHostingController(rootView: LiveView())

Related

SwiftUI bottom sheet like note app's format tab

Currently, I have to implement bottom sheet. And I found the very example of my need.
Is this component system component of swift or swiftui?
OR do I need to implement on my own?
PLEASE LET ME KNOW IF U HAVE SOME INFOS! XD
At first I implement with ZStack, drag gesture but the animation is not what I expected.
I need Information about whether there is component like .sheet(isPresented: Bool, content: View) of the modal like above image.
As our friend said before, it is a sheet. Inside the sheet you can either define a new view or call any of your views. Then you have to use the modifier .presentationDetents which receive a Set of PresentationDetents to say where the view has to stop when appearing on the screen. This modifier must be apply to the content of the sheet and not directly to the sheet.
struct ContentView: View {
#State var isSheetShown = false
var body: some View {
VStack {
Button("Show view"){
isSheetShown = true
}
}.sheet(isPresented: $isSheetShown, content: {
StackOfButtons()
.presentationDetents([.medium])
})
.padding()
}
}
Finally, to create that stack type of buttons you can put them all in a HStack, give them individually some padding, set a little of spacing in the HStack and the round the corners of the stack. Something like this:
struct StackOfButtons: View {
var body: some View {
HStack(spacing: 2){
Button {
print("Hola que ase")
} label: {
Image(systemName: "list.bullet")
.padding()
.background(.thinMaterial)
.foregroundColor(.black)
}
Button {
print("Hola que ase")
} label: {
Image(systemName: "list.dash")
.padding()
.background(.thinMaterial)
.foregroundColor(.black)
}
Button {
print("Hola que ase")
} label: {
Image(systemName: "list.number")
.padding()
.background(.thinMaterial)
.foregroundColor(.black)
}
}.cornerRadius(10)
}
}
Result

SwiftUI Is there any built in view that kind of slides in from the side and takes up 3/4 of the screen?

This is probably a custom view but in the Reddit app there's a toolbar and the top left button(3 lines) opens this kind of view from the side that moves the current view to the right so you can only see about 25% of it and a new view that takes up about 75% of the screen slides in. Is there anything like this built into SwiftUI and if there isn't how would I go about implementing something like this?
This is my custom side bar behave similarly to what you just mentioned, you can try it. (Images and Code are below)
Before click:
After clicked:
struct ContentView: View {
#State var isClicked = false
var body: some View {
HStack {
Rectangle()
.fill(.orange)
.frame(width: isClicked ? UIScreen.main.bounds.width * 0.75 : 0)
VStack {
HStack {
Button {
withAnimation {
isClicked.toggle()
}
} label: {
Image(systemName: "menucard.fill")
.padding(.leading)
}
Spacer()
}
Spacer()
}
}
}
}

Button Text Out-Of-Sync with Tappable Area

I have a navigation view with tab views inside. The reason for this arrangement is to make the tab views disappear when within the navigation views.
I am trying to place a button at the top right corner of the screen (outside the safe area). If EntryView is called directly, the view correctly places the button ("Save") in the corner without use of offset() or position() view modifiers.
When the tab view is called before EntryView, the Save button appears an inch or so below where I would like it to appear. With offset() or position() I can move the button text back where I would like it to appear, but the tappable area doesn't move to the new location.
I have tried different arrangements of ZStack and VStack, but the arrangement below is the closest I have come to getting the button to work in the upper right corner.
Here is where I would like the button to appear: https://i.stack.imgur.com/AMdKQ.png
Is there any way to move the tappable area up to where the text is located?
Or is there some better way to draw the top part of the view?
This code can be dropped directly into Xcode for analysis.
struct ContentView: View {
#State private var selectedTab: Tabs = .home
var body: some View {
NavigationView {
TabView (selection: $selectedTab) {
EntryView()
.tabItem {
Label("Home", systemImage: "house.circle.fill")
}.tag(Tabs.home)
HistoryView()
.tabItem {
Label("History", systemImage: "clock.fill")
}.tag(Tabs.history)
}
}
}
}
struct EntryView: View {
var body: some View {
GeometryReader { g in
ZStack (alignment: .top) {
Color.blue
.frame(height: (g.safeAreaInsets.top) * 0.6, alignment: .top)
.ignoresSafeArea()
HStack {
Spacer()
Button(action: {
print("Save tapped!")
}) {
Text("Save")
.font(Font.title3.bold())
.foregroundColor(.red)
.offset(y: g.size.height * -0.14)
// .position(x: g.size.width * 0.90, y: g.size.height * -0.115)
}
}
.padding(.trailing, 10)
}
}
}
}
struct HistoryView: View {
var body: some View {
VStack (alignment: .leading) {
Text("History Tab")
.padding(.top)
}
}
}
enum Tabs: String {
case home
case history
}

Customize navigationBar in Swift UI

I am new in swift ui. I want to put image button on the side of the NavigationBar title.
I want to be able to click the user image and navigate to another view. How?
You need to use navigationBarItems for putting image to navigation bar and you should add NavigationLink to that image. For center the title you need to set navigation bar title's displayMode to .inline or you can use new Toolbar api
struct ContentView: View {
var body: some View {
NavigationView {
Text("Welcome to Stack Overflow")
.navigationBarTitle("Header", displayMode: .inline)
.navigationBarItems(leading: NavigationLink(destination: Text("Destination")) {
Image(systemName: "person.crop.circle.fill")
.font(.title)
})
}
}
}
Screenshot
Another way using toolbar item.
I am adding TapGesture on image icon, and keeping it out of navigation link, as the image is not getting circular inside the NavigationLink in ToolbarItemGroup.
By leveraging isActive property of NavigationLink which monitors onTap state we can determine either we want to push our view or not.
import SwiftUI
struct WeatherView: View {
#State var onTap = false
var borderColor: Color = Color("Black")
var addProjectToolbarItem: some ToolbarContent {
ToolbarItemGroup(placement: .navigationBarLeading) {
NavigationLink(destination:Text("Welcome"), isActive: self.$onTap) {
EmptyView()
}
Image("yourImage")
.resizable()
.frame(width: 32, height: 32)
.clipShape(Circle())
.onTapGesture {
onTap.toggle()
}
}
}
var body: some View {
NavigationView {
VStack {
Text("First view")
}
.toolbar{
addProjectToolbarItem
}
.navigationTitle("Header")
.navigationBarTitleDisplayMode(.inline)
}
}
}

How can i create TabView with Headers on top not bottom in SwiftUI

How can i make a SwiftUI TabView with headers aligned to top rather than the bottom.
Thanks
This is not directly supported by SwiftUI but you could make your own custom view and here is a simple example on how to do that:
struct ContentView: View {
#State var selectedTab = Tabs.FirstTab
var body: some View {
VStack {
HStack {
Spacer()
VStack {
Image(systemName: "airplane")
.foregroundColor(selectedTab == .FirstTab ? Color.red : Color.black)
Text("First tab")
}
.onTapGesture {
self.selectedTab = .FirstTab
}
Spacer()
VStack {
Image(systemName: "person.fill")
.foregroundColor(selectedTab == .SecondTab ? Color.red : Color.black)
Text("Second tab")
}
.onTapGesture {
self.selectedTab = .SecondTab
}
Spacer()
VStack {
Image(systemName: "cart.fill")
.foregroundColor(selectedTab == .ThirdTab ? Color.red : Color.black)
Text("Third tab")
}
.onTapGesture {
self.selectedTab = .ThirdTab
}
Spacer()
}
.padding(.bottom)
.background(Color.green.edgesIgnoringSafeArea(.all))
Spacer()
if selectedTab == .FirstTab {
FirstTabView()
} else if selectedTab == .SecondTab {
SecondTabView()
} else {
ThirdTabView()
}
}
}
}
struct FirstTabView : View {
var body : some View {
VStack {
Text("FIRST TAB VIEW")
}
}
}
struct SecondTabView : View {
var body : some View {
Text("SECOND TAB VIEW")
}
}
struct ThirdTabView : View {
var body : some View {
Text("THIRD TAB VIEW")
}
}
enum Tabs {
case FirstTab
case SecondTab
case ThirdTab
}
NOTE: I haven't put much effort in aligning the tabs perfectly and used Spacers for simplicity (because this is not relevant to the question). Also I have put all the code so that you could create new empty project and copy-paste it to try and understand how it works.
Lets go through it:
The Tabs enum is created for simplicity
The selectedTab variable is keeping track of which tab is currently selected
I am using if-else construction to display the selected view (as of SwiftUI 2.0 there is also a switch-statement, but since you didn't specify what versions are you using I am using if-else)
The tab view itself is nothing more than Image & Text views aligned to look like the TabView
The foregroundColor modifier using ternary operator is simulating TabView's accent color
When tapped, each Text + Image combination (which replaces buttons on the normal TabView) changes the state to select its view as visible (you could also use buttons with action instead of .onTapGesture I used this for the simplicity of the example)
Here is the result: