How do you fill entire Button area with background View in WatchOS? - swift

I am trying to have my background view span the entire area of a Button on an Apple Watch form factor.
struct SurveyView: View {
var body: some View {
Button(action: {
print("Test tapped.")
}) {
HStack {
Text("Test")
.fontWeight(.semibold)
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(LinearGradient(gradient: Gradient(colors: [.green, .blue]), startPoint: .leading, endPoint: .trailing))
}
}
}
How can I make the background span the entire Button?
Update: Turns out my issue is also related to being in a List View. Setting a mask doesn't quite solve it.
struct SurveyView: View {
var body: some View {
List() {
Button(action: {
print("Test tapped.")
}) {
Text("Test")
.fontWeight(.semibold)
}
.background(Color.orange)
.mask(RoundedRectangle(cornerRadius: 24))
}
}
}

I would do this in the following way:
Button(action: {
print("Test tapped.")
}) {
Text("Test")
.fontWeight(.semibold)
.padding()
.foregroundColor(.white)
}
.background(LinearGradient(gradient: Gradient(colors: [.green, .blue]), startPoint: .leading, endPoint: .trailing))
.mask(RoundedRectangle(cornerRadius: 24))
Update: the case for list
var body: some View {
List() {
Button(action: {
print("Test tapped.")
}) {
Text("Test")
.fontWeight(.semibold)
.padding()
}
.background(Color.orange)
.mask(RoundedRectangle(cornerRadius: 24))
.listRowPlatterColor(Color.clear)
}
}

Related

Can't display custom pop-up because my tab view is in NavigationView

I want to display a pop-up in my view, where I will be able to display a menu where I can choose how I fell, then it will show what I have chosen and close itself. If I am adding it to the view and it's presenting It shows wrong and Tab Bar does not disappear. Can someone provide a better way to show a pop-up over Tab Bar? The logic is something like this: button pressed -> shows pop-up -> choose status -> shows another pop-up -> disappears.
Code's provided below:
// Smile face that used in question
struct SmileFace: View {
var text: String
var image: String
#Binding var current: String
var body: some View {
Button {
withAnimation {
current = text
}
} label: {
VStack {
Image(image)
.resizable()
.scaledToFill()
.frame(width: 46, height: 46)
Text(text)
.foregroundColor(.white)
}
}
}
}
// Check in answer view
import SwiftUI
struct CheckInAskView: View {
let didClose: () -> Void
var didChose: Bool = false
#State var current: String
var emotions = [
"GREAT" : "good",
"GOOD" : "happy",
"OK" : "moderate",
"BAD" : "sad",
"TERRIBLE" : "verysad"
]
var body: some View {
VStack {
ZStack(alignment: .topLeading) {
Rectangle()
.fill(Color("navigation"))
.cornerRadius(15)
.frame(height: 601)
HStack(alignment: .top) {
ZStack(alignment: .top) {
Circle()
.fill(Color(red: 0.682, green: 0.384, blue: 0.486).opacity(0.10))
.frame(width: 173)
.offset(x: -173/2, y: -90/2)
.clipped()
}
Spacer()
Button {
didClose()
} label: {
ZStack {
Circle()
.fill(Color(red: 0.933, green: 0.933, blue: 0.933).opacity(0.30))
.frame(width: 24)
.clipped()
Image(systemName: "xmark")
.font(.system(size: 15))
.foregroundColor(Color(red: 0.762, green: 0.762, blue: 0.762))
}
.padding(10)
}
}
VStack(alignment: .center) {
Spacer()
Text("How do you feel now?")
.foregroundColor(.white)
.font(.custom("Manrope-Bold", size: 16))
HStack(spacing: 35) {
SmileFace(text: "GOOD", image: "good", current: $current)
}
.padding(.horizontal)
DoubleTextView(topText: "Recommendation for you", buttomText: "We have selected courses based on your goals and \nexperience", topTextSize: 16, buttomTextSize: 14)
BigFrameScrollViewHorizontal()
Spacer()
}
}
.frame(height: 601)
}
.frame(height: 601)
.transition(.move(edge: .bottom))
}
}
// View with all views
struct CheckInView: View {
#StateObject var sheetManager: SheetManager
var body: some View {
VStack {
HStack {
Text("How do you fell now?")
.foregroundColor(.white)
.font(.custom("Manrope-Bold", size: 16))
Spacer()
Button {
} label: {
ZStack {
HStack {
Text("Pass check in")
.padding([.top, .leading, .bottom])
.foregroundColor(.white)
.font(.custom("Manrope-Medium", size: 12))
Image(systemName: "chevron.right")
.foregroundColor(.white)
.font(.system(size: 15))
.padding(.trailing)
}
}
.background(Rectangle()
.fill(Color("active"))
.cornerRadius(100)
.frame(height: 26))
}
}
VStack {
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
Divider()
.background(Color("inactive"))
.padding(.vertical)
}
HStack {
Button {
} label: {
ZStack {
Circle()
.fill(Color("navigation"))
.frame(width: 26)
Image(systemName: "chevron.left")
.foregroundColor(.white)
.font(.system(size: 14))
}
}
Button {
} label: {
ZStack {
Circle()
.fill(Color("navigation"))
.frame(width: 26)
Image(systemName: "chevron.right")
.foregroundColor(Color("inactive"))
.font(.system(size: 14))
}
}
}
.padding(.top)
}
.padding(.horizontal, 15.0)
}
}
struct CheckInView_Previews: PreviewProvider {
static var previews: some View {
CheckInView(sheetManager: SheetManager())
.background(.yellow)
}
}
If I have all of this, how can I create a pop-up over Tab View? Maybe a link to a similar problem?

SwiftUI button glitches on keyboard dismiss

I have a button on my view that, when pressed, calls a hideKeyboard function which is the following:
func hideKeyboard() {
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
}
However, when the button is pressed and the keyboard gets dismissed, a glitch occurs where the button stays in place while the view moves downward:
https://giphy.com/gifs/Z7qCDpRSGoOb9CbVRQ
Reproducible example:
import SwiftUI
struct TestView: View {
#State private var username: String = ""
#State private var password: String = ""
#State private var isAnimating: Bool = false
var lightGrey = Color(red: 239.0/255.0,
green: 243.0/255.0,
blue: 244.0/255.0)
var body: some View {
ZStack() {
VStack() {
Spacer()
Text("Text")
.font(.title)
.fontWeight(.semibold)
.padding(.bottom, 15)
.frame(maxWidth: .infinity, alignment: .leading)
Text("Text")
.font(.subheadline)
.padding(.bottom)
.frame(maxWidth: .infinity, alignment: .leading)
TextField("username", text: $username)
.padding()
.background(self.lightGrey)
.cornerRadius(5.0)
.padding(.bottom, 20)
SecureField("password", text: $password)
.padding()
.background(self.lightGrey)
.cornerRadius(5.0)
.padding(.bottom, 20)
Button(action: {
self.hideKeyboard()
login()
})
{
if isAnimating {
ProgressView()
.colorScheme(.dark)
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
}
else {
Text("Text")
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
}
}
.disabled(username.isEmpty || password.isEmpty || isAnimating)
Text("Text")
.font(.footnote)
.frame(maxWidth: .infinity, alignment:.leading)
Spacer()
}
.padding()
.padding(.bottom, 150)
.background(Color.white)
}
}
func hideKeyboard() {
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
}
func login() {
isAnimating = true
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
This is due to view replacement inside button, find below a fixed re-layout.
Tested with Xcode 13.2 / iOS 15.2 (slow animation was activated for demo)
Button(action: {
self.hideKeyboard()
login()
})
{
VStack { // << persistent container !!
if isAnimating {
ProgressView()
.colorScheme(.dark)
}
else {
Text("Text")
}
}
.foregroundColor(.white)
.font(.headline)
.padding()
.frame(maxWidth: .infinity)
.background(Color.green)
.cornerRadius(10.0)
.padding(.bottom, 20)
}
.disabled(username.isEmpty || password.isEmpty || isAnimating)
Looks like a conflict between UIApplication.shared.sendAction and SwiftUI: hiding the keyboard starts the animation, but updating the isAnimating property resets it.
Changing the order of calls solves the problem:
Button(action: {
login()
self.hideKeyboard()
})

Adding a "Hamburger" Menu to IOS application

I am trying to create a hamburger menu that when you click the "hamburger" (three horizontal lines) button, the menu will slide out. I am following the tutorial found here, but the only thing that isn't working is the lines for the Hamburger image is not showing up on my application. Everything else works, but for some reason this is the one thing that is not working.
Here is my code for the ContentView, where it hosts the problem code
struct ContentView: View {
#State var showMenu = false
var body: some View {
let drag = DragGesture()
.onEnded {
if $0.translation.width < -100 {
withAnimation {
self.showMenu = false
}
}
}
return NavigationView {
GeometryReader { geometry in
ZStack(alignment: .leading) {
MainView(showMenu: self.$showMenu)
.frame(width: geometry.size.width, height: geometry.size.height)
.offset(x: self.showMenu ? geometry.size.width/2 : 0)
.disabled(self.showMenu ? true : false)
if self.showMenu {
MenuView()
.frame(width: geometry.size.width/2)
.transition(.move(edge: .leading))
}
}
.gesture(drag)
}
.navigationBarTitle("Side Menu", displayMode: .inline) // this works
//somewhere below here is the problem
.navigationBarItems(leading: (
Button(action: {
withAnimation {
self.showMenu.toggle()
}
}) {
Image(systemName: "three_horizontal_lines")
.imageScale(.large)
}
))
}
}
}
Here is the MainView:
struct MainView: View{
#Binding var showMenu: Bool
var body: some View{
Button(action: {
withAnimation{
self.showMenu = true
}
}){
Text("Show Menu")
}
}
}
Lastly, this is the MenuView:
struct MenuView: View{
var body: some View{
VStack(alignment: .leading){
HStack{
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 100)
HStack{
Image(systemName: "envelope")
.foregroundColor(.gray)
.imageScale(.large)
Text("Messages")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
HStack{
Image(systemName: "gear")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
Spacer()
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(/*#START_MENU_TOKEN#*/.all/*#END_MENU_TOKEN#*/)
}
}
I have checked for any misspellings and even copied and pasted the code from the original tutorial, but it seems nothing allows me to see the burger image like is shown on the tutorial. Any thoughts on what else I could try?

why my logout button can logout but can't switch the view

I have already set a logout button. The function of that button is correct which can actually logout. But there is a problem: when I press the logout button, I can not switch the page to the view I want, which is LoginsignupView. I can't find amything wrong in my code.
I want to know how to make it correctly.
Here is the code about logout
import SwiftUI
struct MainView: View {
#State private var selection = 0
#ObservedObject private var httpClient = HTTPUser()
#State var isin : Bool = true
var body: some View {
if #available(iOS 14.0, *) {
ZStack{
TabView(selection: $selection){
profile1View()
.tag(0)
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
//List(self.httpClient.user,id: \.id){ user in
profile3()
.tag(1)
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
ZStack{
Image("background")
.resizable()
.scaledToFill()
.frame(minWidth: 0, maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
NavigationLink(
destination: LoginsignupView().navigationBarBackButtonHidden(true)
.navigationBarHidden(true))
{
Text("logout").foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 100)
.background(
LinearGradient(gradient: .init(colors: [Color("Color"),Color("Color1"),Color("Color2")]), startPoint: .leading, endPoint: .trailing)
)
}
}
.tag(2)
.onAppear(perform: httpClient.Logout)
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}
.zIndex(0)
.onAppear{
UITabBar.appearance().barTintColor = .white
}
}
}
if #available(iOS 14.0, *) {
TabBarView(selection: $selection)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
} else {
// Fallback on earlier versions
}
Divider()
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
If the intent is to push a LoginSignupView once "Logout" is pressed, then you need a NavigationView somewhere in the view hierarchy. NavigationLink itself won't do much.
However, from your code it looks like you perform logout once the last tab is shown. In which case you might also want to bind your existing NavigationLink to a boolean property. For example your tab might look like this:
NavigationView {
.....
ZStack{
Image("background")
.resizable()
.scaledToFill()
.frame(minWidth: 0, maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
NavigationLink(
destination: LoginsignupView().navigationBarBackButtonHidden(true)
.navigationBarHidden(true), isActive:$showingLogout)
{
Text("logout").foregroundColor(.white)
.fontWeight(.bold)
.padding(.vertical)
.frame(width: UIScreen.main.bounds.width - 100)
.background(
LinearGradient(gradient: .init(colors: [Color("Color"),Color("Color1"),Color("Color2")]), startPoint: .leading, endPoint: .trailing)
)
}
}
.tag(2)
.onAppear(perform: {
httpClient.Logout()
showingLogout = true
})
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}

Filling HStack swiftUI

I want to create a button stack like having a play and record button using SwiftUI, after creating it just does not look anything like what I wanted.
var body: some View {
HStack(alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/, spacing: 8) {
Spacer()
Button(action: {
print("Recordinggg")
}, label: {
Text("Record")
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(40.0)
})
Spacer()
Button(action: {
print("Recordinggg")
}, label: {
Text("Play")
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(40.0)
})
Spacer()
}
}
What I actually want is something like this
Use proper frame, padding you can achieve this. Here is an example code.
Create ButtonStyle.
struct ThemeButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.padding([.top, .bottom], 10)
.foregroundColor(.white)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
.background(Color.blue)
.cornerRadius(40.0)
}
}
Your view
struct ContentView: View {
#State private var phase: CGFloat = 0
var body: some View {
HStack(alignment: .center, spacing: 0) {
Button(action: {
print("Recordinggg")
}, label: {
Text("Record")
})
.buttonStyle(ThemeButtonStyle())
Spacer()
Button(action: {
print("Recordinggg")
}, label: {
Text("Play")
})
.buttonStyle(ThemeButtonStyle())
}
.padding()
}
}