I have a tab bar with 2 TabItems, What I want is to have one of the tab item's view beeing transparant.
ZStack {
Color.clean
TabView {
if #available(iOS 15.0, *) {
HomeView()
.tabItem {
Label("Home", systemImage: "person.crop.circle")
}
} else {
// Fallback on earlier versions
}
PatientView()
.tabItem {
Label("Patient", systemImage: "heart.text.square.fill")
}
}
}
I have tried to add an EmptyView() but i didn't get the desired result. HomeView should be transparent but also having 2 buttons displayed.
struct HomeView: View {
var body: some View {
if showLoadingSpinner {
ZStack {
Color.backgroundColor.edgesIgnoringSafeArea(.all)
ProgressView("Loading Avatar")
.progressViewStyle(CircularProgressViewStyle(tint: Color.brandPrimary))
}
.onAppear{
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
showLoadingSpinner = false
}
}
}
else {
GeometryReader { geometry in
ZStack {
VStack {
CreateZipMetadataView()
}
.frame(maxHeight: .infinity, alignment: .top)
.padding(.leading, UIScreen.screenWidth/2 - (geometry.size.width/7)/2)
EmptyView()
.frame(maxHeight: .infinity)
ZStack {
Circle()
.foregroundColor(.white)
.frame(width: geometry.size.width/7, height: geometry.size.width/7)
.padding(.leading, UIScreen.screenWidth/2 - (geometry.size.width/7)/2)
.frame(maxHeight: .infinity, alignment: .bottom)
}
}
}
Related
I created some MRE:
struct ContentView: View {
#State private var presentOverlay: Bool = false
var body: some View {
GeometryReader { geo in
List {
Section {
VStack(alignment: .center) {
Spacer()
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
.onTapGesture {
presentOverlay.toggle()
}
Text("Hello, world!")
}
.frame(height: geo.size.height * 0.8)
} header: {
Text("Header")
} footer: {
Text("Footer")
}
}
.overlay(alignment: .bottom) {
if presentOverlay {
Text("Some overlay")
.frame(width: geo.size.width, height: geo.size.height * 0.2)
.background(.yellow)
.transition(.move(edge: .bottom))
}
}
}
.animation(.default, value: presentOverlay)
}
}
Goal is to, when overlay appears, move content of list, so Image can be presented and clickable (currently overlay is going above it).
Is it possible to move content like it is scrolled using List component?
**
Hello everybody.
i applied the above indicator, but the image but i still see only about half screen. the bottom remains gray. I applied ".onAppear () {
UITableView.appearance (). BackgroundColor = UIColor.clear} "because I would like to have transparency and see the whole image below and leave only the part of the list highlighted, but under the list I have only the gray screen and not the image. Basically no transparencies are applied through .
'''
var body: some View {
NavigationView {
ZStack {
VStack { // DEFINISCO IL NEW TASK
VStack(spacing: 16) {
TextField("New Task", text: $task)
.padding()
.background(
Color(UIColor.systemGray6)
)
.cornerRadius(10)
Button(action: {
addItem()
}, label: {
Spacer()
Text("SAVE")
Spacer()
})
.disabled(isButtonDisabled)
.padding()
.font(.headline)
.foregroundColor(.white)
.background(isButtonDisabled ? Color.gray : Color.pink)
.cornerRadius(10)
} //: VSTACK
.padding()
List {
ForEach(items) { item in
VStack(alignment: .leading) {
Text(item.task ?? "")
.font(.headline)
.fontWeight(.bold)
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
.font(.footnote)
.foregroundColor(.gray)
}
}
.onDelete(perform: deleteItems)
} //: LIST
.listStyle(InsetGroupedListStyle())
.shadow(color: Color(red: 0, green: 0, blue: 0,opacity: 0.3),
radius: 12)
.padding(.vertical, 0)
.frame(maxWidth: 640)
} //: VSTACK
} //: ZSTACK
.onAppear() {
UITableView.appearance().backgroundColor = UIColor.clear
}
.navigationTitle("Daily Tasks")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
} //: TOOLBAR
.background(
BackgroundImageView()
)
.background(
backgroundGradient.ignoresSafeArea(.all)
)
Text("Select an item")
} //: NAVIGATION VIEW
}
I want to make a segment tab page in SwiftUI such as bellow.
My code is as bellow:
struct ContentView: View {
#State var index = 0
#State private var offset: CGFloat = 0
var body: some View {
VStack(spacing: 0) {
HStack() {
Button("tab1") {
self.index = 0
}
Button("tab2") {
self.index = 1
}
}
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 0) {
VStack() {
List {
VStack {
HStack() {
Text("tab1 line1")
Spacer()
}
.frame(height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab1 line1")
}
}
VStack {
HStack() {
Text("tab1 line2")
Spacer()
}
.frame(height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab1 line2")
}
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.cornerRadius(30)
VStack() {
List {
VStack {
HStack() {
Text("tab2 line1")
Spacer()
}
.frame(width: UIScreen.main.bounds.size.width, height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab2 line1")
}
}
VStack {
HStack() {
Text("tab2 line2")
Spacer()
}
.frame(width: UIScreen.main.bounds.size.width, height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab2 line2")
}
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.onAppear() {
print("load")
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.cornerRadius(30)
}
}
.content
.offset(x: self.getOffset())
.animation(.spring())
.frame(width: UIScreen.main.bounds.size.width, alignment: .leading)
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.background(Color.gray)
}
private func getOffset() -> CGFloat {
let offset = CGFloat(self.index) * (-UIScreen.main.bounds.size.width)
return offset
}
}
Everything works well expect the onTapGesture in tab2. When tap the line of "tab1",the onTapGesture works well to print "click tab1 line1" or "click tab1 line2".
After click button "tab2", the page will scroll to tab2 page. When click the line of list "tab2", onTapGesture not works.
I try a day, and found two methods to make it works:
After scroll to page "tab2", Scroll up or down the tab2 list, the onTapGesture will works to print "click tab2 line1" and "click tab2 line2".
remove the code .cornerRadius(30), the click in tab2 page will also works.
I just want to keep the radius of list. How to fix this incredible bug?
The problem is here:
.content
.offset(x: self.getOffset())
This duplicates the scrollview's content and offsets it to the right. As a result, what you are tapping is the duplicated content, which probably affects the tap gesture.
Instead, use ScrollViewReader to scroll the ScrollView, and remove your getOffset code.
struct ContentView: View {
#State var index = 0
#State private var offset: CGFloat = 0
var body: some View {
VStack(spacing: 0) {
HStack() {
Button("tab1") {
self.index = 0
}
Button("tab2") {
self.index = 1
}
}
ScrollView(.horizontal, showsIndicators: false) {
ScrollViewReader { proxy in
HStack(alignment: .center, spacing: 0) {
VStack() {
List {
VStack {
HStack() {
Text("tab1 line1")
Spacer()
}
.frame(height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab1 line1")
}
}
VStack {
HStack() {
Text("tab1 line2")
Spacer()
}
.frame(height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab1 line2")
}
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.cornerRadius(30)
.id(0) /// set id here
VStack() {
List {
VStack {
HStack() {
Text("tab2 line1")
Spacer()
}
.frame(width: UIScreen.main.bounds.size.width, height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab2 line1")
}
}
VStack {
HStack() {
Text("tab2 line2")
Spacer()
}
.frame(width: UIScreen.main.bounds.size.width, height: 126)
.contentShape(Rectangle())
.onTapGesture {
print("click tab2 line2")
}
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.onAppear() {
print("load")
}
}
.frame(width: UIScreen.main.bounds.size.width, height: 300)
.cornerRadius(30)
.id(1) /// also set id here
}
.onChange(of: index) { _ in /// scroll the ScrollView
withAnimation(.spring()) {
proxy.scrollTo(index)
}
}
}
}
.frame(width: UIScreen.main.bounds.size.width, alignment: .leading)
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.background(Color.gray)
}
}
I made a card style List row which work fine. The issue is that the list row background color remains. I can make it disappear by setting it to systemGray6 but it's not very adaptive for dark mode and there is very likely a better way of doing this.
Card View:
var body: some View {
ZStack {
Rectangle().fill(Color.white)
.cornerRadius(10).shadow(color: .gray, radius: 4)
.frame(width: UIScreen.main.bounds.width - 40)
HStack {
Image(uiImage: (UIImage(data: myVideo.thumbnailImage!) ?? UIImage(systemName: "photo"))!)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100, height: 100)
VStack {
Text(myVideo.title!)
.multilineTextAlignment(.center)
.font(.body)
.padding(.bottom, 10)
.frame(maxWidth: UIScreen.main.bounds.width - 40, maxHeight: .infinity, alignment: .center)
Text(myVideo.youtuber!)
.font(.subheadline)
}
}
.padding(5)
}
}
List View:
var body: some View {
NavigationView {
if myVideos.isEmpty {
Text("You have not added videos yet!")
font(.subheadline)
} else {
List() {
Section(header: Text("Not Watched")) {
ForEach(myVideos) { video in
if !video.watched {
NavigationLink(destination: MyVideoView(myVideo: video)) {
MyListRowView(myVideo: video)
}
}
}
.onDelete(perform: removeItems)
}
Section(header: Text("Watched")) {
ForEach(myVideos) { video in
if video.watched {
NavigationLink(destination: MyVideoView(myVideo: video)) {
MyListRowView(myVideo: video)
}
}
}
.onDelete(perform: removeItems)
}
.listRowBackground(Color(UIColor.systemGray6))
}
.navigationBarTitle("Videos")
.listStyle(GroupedListStyle())
}
}
}
Image: (Intended behaviour in "WATCHED" and Incorrect behaviour in "NOT WATCHED"
As the picture shows, I want the button to be in the bottom right corner.
https://i.imgur.com/GiVor8a.png
var body: some View {
ZStack {
HStack {
Color.black
}
Button(action: {}) {
HStack {
Image(systemName: "rectangle.grid.1x2.fill")
}
.padding()
.background(Color.yellow)
.mask(Circle())
}.frame(width: 60, height: 60)
.border(Color.red, width: 1)
}
}
You can use Spacer() for that,
Here is Your Code :
ZStack {
HStack {
Color.black
}
VStack(alignment:.trailing) {
Spacer()
HStack {
Spacer()
Button(action: {}) {
HStack {
Image(systemName: "rectangle.grid.1x2.fill")
}
.padding()
.background(Color.yellow)
.mask(Circle())
}.frame(width: 60, height: 60)
.border(Color.red, width: 1)
}
}
}