Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I want to print the name of each swiftUI but on run time if it’s possible
Im trying to print out the name of a swiftUI view like on swift type(of:) but nothing. Any idea?
try something like this, to ...get the name of a SwiftUI view programmatically:
struct MyView: View {
#State var viewName = ""
var body: some View {
Text(viewName)
.onAppear {
viewName = "\(Self.self)"
}
}
}
Or simply:
struct MyView: View {
let viewName = "\(Self.self)"
var body: some View {
Text(viewName)
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
UPDATE: Let's put it very simple. This:
struct FavoriteButton: View {
#Binding var items : [Item]
var body: some View {
Button("Toggle") {
.....
}
}
}
You have the item at your disposal, not the array to pass in FavoriteButton(items: [something]). If you just create the array it will break the binding as it is the struct not the class and it will not keep the reference. Can you pass it somehow and keep the binding?
ORIGINAL QUESTION (which also explains why):
I have a List in SwiftUI. Let's say that it is bound to [Item] array and that there is a property Item.isFavorite that triggers visual change in a row. The item should be handled by the FavoriteButton that can be triggered by the single item like in swipeActions or by multiple items like in contextMenu(forSelection:).
The question is whether it is possible to do this by passing an item array to the button? My problem is that array needs to be passed as the binding so that changing of the isFavorite updates the view, and if I create a new array from the single item I seem to be unable to keep the binding.
One possible solution is to pass the item id array and then do the work in the view model (this way I don't need to keep the binding in the button). However I am particularly interested in whether it is possible to be done by passing the item array to the button and binding. I am aware that the solution with just using ids and view model might be better, but for some curiosity I am interested if this is possible (I think it should be).
EDIT: as some people asked for clarification, I'll copy it from my comment below where I have provided it:
You have a FavoriteButton view that has #Binding var items : [Item]. You only have Item (not an array) when creating the FavoriteButton at your disposal. How do you pass it as the array that keeps the binding to the original item?
This is really a most entertaining comment thread and it feels like reverse engineering code from a textual descriptions can become a new sport. Might be something for ChatGPT ;) And yes, I will delete this intro soon.
But here comes a suggestion for what I tried to understand. isFavourite can be toggled either by the new .contextMenu(forSelectionType) or the described FavoriteButton. I might be way off, just let me know :)
struct Item: Identifiable {
let id = UUID()
var name: String
var isFavorite = false
}
struct ContentView : View {
init() {
var dummy = [Item]()
for i in 1...10 {
dummy.append(Item(name: "Item \(i)"))
}
self._data = State(initialValue: dummy)
}
#State private var data: [Item]
#State private var selection: UUID?
var body: some View {
List(data, selection: $selection) { item in
HStack {
Image(systemName: "heart").opacity(item.isFavorite ? 1 : 0)
Text(item.name)
Spacer()
FavoriteButton(items: $data, selection: item.id)
}
.swipeActions {
FavoriteButton(items: $data, selection: item.id)
}
}
.contextMenu(forSelectionType: UUID.self) { indices in
FavoriteButton(items: $data, selection: indices.first)
}
}
}
struct FavoriteButton: View {
#Binding var items : [Item]
let selection: Item.ID?
var body: some View {
Button("Toggle") {
if let index = items.firstIndex(where: { $0.id == selection }) {
items[index].isFavorite.toggle()
}
}
}
}
Edit: now with FavoriteButton also used inside contextMenu.
Edit2: now with FavoriteButton also used in .swipeActions
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 10 months ago.
Improve this question
I want to show/hide progress view in swiftUI globally. I have api class for api calling but I want to show progressview when api calling.. how can I do that
class NetworkManager: NSObject {
static let shared = NetworkManager()
//MARK:- ======== FETCH API DATA =========
func fetchAPIData(url:String,
isShowHUD:Bool){
headerDic["timezone"] = TimeZone.current.identifier
if isShowHUD {
// I want to show progressview from here top of the screen.
}
**api calling code.**
}
}
}
Here if I pass isShowHUD then show progress view on top of the screen. if any error or got the response then it hide the progressview.
Please help me on that.how can I achieve in swift ui.I am in new in swift UI.
You'd need to add a ProgressView and you'd need a variable to notify when loading has finished when it's successful. Documentation on ProgressView can be found here. Without giving you the full answer he's a simple solution to add a ProgressView when doing some kind of network request.
class Network: ObservableObject {
#Published var loading = true
func fetchapidata() {
/*
Network request goes here, is successful change loading to false
*/
self.loading = false
}
}
struct ContentView: View {
#StateObject var network = Network()
var body: some View {
NavigationView {
List {
/*
Details go here
*/
}
.overlay {
if network.loading {
ProgressView("Loading")
}
}
.listStyle(.plain)
.navigationTitle("Title")
}
.navigationViewStyle(.stack)
.onAppear {
network.fetchapidata()
}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Confused between TupleView and AnyView, Can anyone explain in detail TupleView and AnyView?
AnyView is a type-erased View. It is necessary for overcoming some of the type system limitations. For example, the following does not compile:
import SwiftUI
struct SomeView: View {
#State private var showText: Bool
var body: some View {
if showText {
return Text("This is text.")
} else {
return Rectangle()
}
}
}
This is because some View requires that the same concrete View type is returned in every possible case. We can't return Text in one case and Rectangle or whatever else in another.
We can't use View (without some) either, as protocols with associated types can't be used as a concrete type.
This is where AnyView comes to the rescue:
import SwiftUI
struct SomeView: View {
#State private var showText: Bool
var body: some View {
if showText {
return AnyView(Text("This is text."))
} else {
return AnyView(Rectangle())
}
}
}
In general, you can use AnyView whenever you want to hide a concrete type and just return View. This is not unique to SwiftUI. AnyCollection, AnySequence etc. play the same role.
TupleView is a concrete View type uses to store multiple View values. It's rarely used, mostly by library developers for implementing view builders, something like this:
struct MyView: View {
init<C0, C1>(
#ViewBuilder _ content: #escaping () -> TupleView<(C0, C1)>
) where C0: View, C1: View {
let content = content().value
// do something with content
}
// implement the rest of the view
}
MyView can now be used with the special syntax, like this:
MyView {
View1()
View2()
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am new to MVVM. How should I update the data model in parent view model from child view model?
As an example, suppose I have a CollectionViewModel for a Newsfeed page, it keeps an array of Post (my date model) and an array of CollectionCellViewModel that corresponds to individual posts. Each cell makes network request to listen for new likes. How can I pass this information back to CollectionViewModel and update Post?
You achieve that with multiple ways:
Delegation pattern:
protocol CollectionCellViewModelDelegate {
func onAction()
}
class CollectionCellViewModelDelegate: YourType {
var delegate: CollectionCellViewModelDelegate?
/// Your custom action
func yourCustomAction() {
delegate?.onAction
}
}
then assign .delegate in your parent class and implement onAction() method
Closures:
class CollectionCellViewModelDelegate: YourType {
var yourAction: (()->())?
func yourAction(_ completion: (()->())?) {
yourAction = completion
}
/// Your custom action
func yourCustomAction() {
yourAction?()
}
}
then call your closure with following code from parent class:
child.yourAction { // do custom stuff }
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a date picker, I want to save the value user gave, so next time user goes back to that view controller, the date picker is still set to the value given last time.
Here's my code:
import UIKit
class Setting: UIViewController {
#IBOutlet weak var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
datePicker.datePickerMode = UIDatePickerMode.Time
// Do any additional setup after loading the view.
}
}
Cast it to a variable then load that variable into the data field!
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html