For example, don't you have another Menu type in you project, including imported modules?
This is a brand new project I'm working on and I'm still creating the UIs. So no other modules/third-party frameworks or anything added yet. And no other objects named Menu either. Very strange. I'm going to replicate this menu part only on another project and see what happens.
Post
Replies
Boosts
Views
Activity
Oh I see. That's unfortunate but I can work around it by comparing the title property values. Thanks a ton for all your help.
btw I changed the ObservableObjects to use generics. It doesn't seem to have an effect on functionality-wise. Everything works ok.
However (this issue actually persisted before changing it to generics too), the SwiftUI preview for this view doesn't get rendered.
swift
class MenuViewObservableT: MenuItem: ObservableObject {
var onButtonTap: ((MenuItem) - Void) = { _ in }
}
struct UserTypeMenuView: View {
@ObservedObject var observable: MenuViewObservableMenu.UserType
private let columns = [
GridItem(.flexible(), spacing: 20),
GridItem(.flexible(), spacing: 20)
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(Menu.UserType.allCases, id: \.self) { item in
MenuButtonMenu.UserType(item: item, action: observable.onButtonTap)
}
}
.padding(.horizontal)
.padding([.top, .bottom], 20)
}
}
}
struct UserTypeMenuView_Previews: PreviewProvider {
static var previews: some View {
UserTypeMenuView(observable: MenuViewObservableMenu.UserType())
}
}
Shows the following error.
'Menu' is ambiguous for type lookup in this context
Thanks a lot @OOPer. Made some good progress thanks to your guidance. One last question if I may.
So I made a MenuItem protocol, made the sub-enums under Menu conform to it, made the MenuButton accept it as a generic parameter.
swift
/* MenuItem */
protocol MenuItem {
var title: String { get }
var image: String { get }
}
/* Menu */
enum Menu {
enum UserType: CaseIterable, MenuItem {
case new
case existing
var title: String {
/ / ..
}
var image: String {
/ / ..
}
}
}
/* MenuViewObservable */
class MenuViewObservable: ObservableObject {
var onButtonTap: ((MenuItem) - Void)!
}
/* UserTypeMenuView */
struct UserTypeMenuView: View {
@ObservedObject var observable: MenuViewObservable
/ / ..
var body: some View {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(Menu.UserType.allCases, id: \.self) { item in
MenuButtonMenu.UserType(item: item, action: observable.onButtonTap)
}
}
}
}
}
/* MenuButton */
struct MenuButtonT: MenuItem: View {
let item: T
var action: (T) - Void
var body: some View {
Button(action: {
action(item)
}) {
/ / ..
}
}
}
Everything works great. Now I can get the title of the menu from where I'm subscribing to the closure.
swift
observable.onButtonTap = { item in
print(item.title)
}
Is there a way to actually get the type of the enum here? So I can do something like this.
swift
observable.onButtonTap = { item in
switch item {
case .new:
/ / ..
case .existing:
/ / ..
}
}
When I print out the type of it like this print(type(of: item)), I see the UserType in the console. But I can't access it.
Thanks for the response @OOPer.
I'm struggling to figure out how to incorporate generics with how I've created my objects, enums inside enums. Would it still work in my case?
I tried this.
swift
struct MenuButtonT: Menu: View {
}
But it's giving me the following error.
Type 'T' constrained to non-protocol, non-class type 'Menu'
My app had a phone number authentication + Facebook auth and it got rejected because it didn't have Sign in with Apple. Apple seriously need to re-write the guidelines to better convey whatever rules they now have.
That green line is the navigation bar of the view controller before this one. In iOS 13, modal views show up like this. With the previous view controller visible under it.