How to return a Button from a function in SwiftUI?
I'm not sure how important it is that you get a Button, but if you just need it to be displayed in another SwiftUI View without further refinements, you can just return some View
. You only have to embed all your Buttons in AnyView's.
func buildButton(parameter : Parameter) -> some View {
switch (parameter){
case Parameter.Value1:
return AnyView(Button(
action: {
...
},
label: {
...
})
)
case Parameter.Value2:
return AnyView(Button(
action: {...},
label: {
...
})
)
}
}
How to return a button from a function WITH modifiers in SwiftUI?
Swift/SwiftUI is picky with the syntax of these things.
To return different types and still conform to some View
, you have to use @ViewBuilder
. Using @ViewBuilder
also means that you use implicit returns, so the structure will be slightly different (no guard let
):
@ViewBuilder func makeButton() -> some View {
if let variable = value {
Button(action: {
//execute a function here
}, label: {
Text("Other Label")
.padding(.vertical, 20)
.frame(width: UIScreen.main.bounds.width * 0.8)
.background(Color.white)
})
} else {
Button(action: {
print("printing now...")
}, label: {
Text("Label")
})
}
}
SwiftUI function that returns either Text or Button?
Here is correct variant.
Note: ViewBuilder
is disabled when you use explicitly return
, so you have to remove return
(s) when use it otherwise you'll get compiler errors again.
Tested with Xcode 12 / iOS 14
@ViewBuilder
private func cellContent(for cell: Cell) -> some View {
if (cell.editable) {
Button(action: { print("hi") }) { Text(cell.content) }
}
Text(cell.content)
}
Returning a SwiftUI List in a function
Option #1:
Return some View
:
func myList() -> some View {
List(items, id:\.self) { item in
Text("Hello")
}
}
Option #2:
Use the specific type. The easiest way I can think of to get this is to temporarily set a variable to the List
. For example:
var myList = List(items, id:\.self) { item in
Text("Hello")
}
If I then Option-Click on myList
, Xcode will display a popup showing the exact type that myList
is inferred to be. You can use that as the return type for your function. In the case of my contrived example, it is List<Never, ForEach<[GameModel], GameModel, Text>>
where items
is [GameModel]
Return value from function (action button)
@IBAction
function is system based functions based on user interaction. They don't return anything and the return type is Void for this type function
SwiftUI: Button inside function doesn't update view
You have @State
defined inside a member function. Instead, it should be defined at the top level of your View
-- that's the only way it will retain/update state. The smallest working change would be this:
struct TestView: View {
@State var testBool: Bool? //<-- Here
var body: some View {
buttonView()
}
func buttonView() -> some View {
Button(action: {
testBool = Bool.random()
}, label: {
VStack {
Text("click me")
Text(testBool == nil ? "nil" : String(testBool!))
}
})
}
}
A further refactor to get it to look a little Swift-ier might be:
struct TestView: View {
@State var testBool: Bool?
var body: some View {
Button(action: {
testBool = Bool.random()
}) {
VStack {
Text("click me")
if let testBool = testBool {
Text(testBool ? "true" : "false")
} else {
Text("nil")
}
}
}
}
}
Button with NavigationLink and function call SwiftUI
The answer from Yodagama works if you were trying to present a sheet (because you called your navigation destination SheetView), but if you were trying to navigate to SheetView instead of present a sheet, the following code would do that.
struct LoginView: View {
@State var check = false
@State var answer = false
var body: some View {
NavigationView {
VStack{
Text("it doesn't work")
NavigationLink(destination: SheetView(), isActive: $answer, label: {
Button(action: {
answer = test(value: 2)
}, label: {
Text("Calculate")
})
})
}
}
}
func test(value: Int) -> Bool {
if value == 1 {
check = false
} else {
print("Succes")
check = true
}
return check
}
}
struct SheetView: View {
var body: some View {
NavigationView {
VStack{
Text("Test")
.font(.title)
}
}
}
}
Related Topics
How to Grant Discoveruserinfowithuserrecordid Permission
Shared Cookies with Wkprocesspool for Wkwebview in Swift
Modal Picker Not Scrolling Right Swiftui
Create Spotlight-Like Window in Swift 4
How to Get a Double Value Up to 2 Decimal Places
How to Create Right Angle View in Swift
How to Replace Limited Number of Occurrences in String
Ios/Tvos Playground Fails with "Unable to Find Execution Service for Selected Run Destination"
Swift Enumeration Order and Comparison
How to Animate Changes to an @Observedobject
Nsdateformatter Detect 24-Hour Clock in Os X and iOS
Swiftui, Shadow Only for Container
Error: Initializer 'Init(_:)' Requires That 'Binding<String>' Conform to 'Stringprotocol'
How to Create an Uppercase Version of a String in Swiftui