Android uses three dots (pictured) to show that there are more menu items available. What is the iOS equivalent of this icon?
It's : ellipsis
and you can use it like this :
Image(systemName: "ellipsis")
There is no clear equivalent, the closest I can think of are the horizontal three dots inside a UITabBarItem when there is no space to show the options:
That being said, contextual menus are not common in iOS apps and there is no default UI item for them.
There is the more system icon from Apple
See all system icons here
If I understand correctly, tapping on the 3 dots shows a new screen with details from the item you've selected? If that's it then on iOS the equivalent is a chevron (>) symbol. It tells you that tapping the entry takes you to a detail screen.
I myself use the "square.and.arrow.up" system icon as my equivalent. Though the Android icon isn't so terrible you could implement it yourself.
Additionally a bottom action sheet is a great equivalent for Android's Contextual Menu.
SwiftUI Implementation of action sheet
.actionSheet(isPresented: $showingActionSheet) {
ActionSheet(title: Text("Change background"), message: Text("Select a new color"), buttons: [
.default(Text("Red")) { self.backgroundColor = .red },
.default(Text("Green")) { self.backgroundColor = .green },
.default(Text("Blue")) { self.backgroundColor = .blue },
.cancel()
])
}
In iOS 14 Apple introduced Pull-Down menus. It should be the closest thing to Android overflow menus. For example, you can add a "more" bar button item to your navigation bar and attach a menu to it.
You can find details about it here: https://developer.apple.com/design/human-interface-guidelines/ios/controls/pull-down-menus/
Related
I was wondering how to show a context menu when holding an element then showing a preview with the menu items in SwiftUI? I know how to show context menu items, but not with the preview and the animation.
View video: https://utilities.awesomeplayer.tech/send/f.php?h=35h_YJr5&p=1
I have tried to attach views inside the Context Menu, before the Buttons, but that has not worked.
Any help would be appreciated!
NOTE: The following is only available in iOS 16+ and iPadOS 16+. Earlier versions in second part. From the docs:
This view modifier produces a context menu on macOS, but that platform doesn’t display the preview.
Take a look at the docs here: https://developer.apple.com/documentation/swiftui/gridrow/contextmenu(menuitems:preview:). In iOS 16+, contextMenu accepts a preview argument that is some View. Example:
struct myViewWithPreview: View{
var body: some View{
Text("Hold for contextMenu")
.contextMenu{
//ContextMenu stuff here
//Such as buttons
Button("Example"){}
} preview: {//<-- HERE!!!!
//Here, put any view that you want as a preview. For example, you could put a webview here on a link.
//You could also do an image, such as how they do it on the docs.
Text("Preview!")
}
}
}
If you are using earlier OS versions, you must do this using a custom approach. Take a look at this article. This could also be of use: https://onmyway133.com/posts/how-to-show-context-menu-with-custom-preview-in-swiftui/.
I select the systemImage "map" and "person" for the tabItem, but the images are in filled format which must be in hollow format. What's the reason?
struct TestView: View {
var body: some View {
TabView {
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
}
Text("Profile")
.tabItem {
Label("Person", systemImage: "person")
}
}
}
}
Xcode: 13.1
SF Symbols: 3.1
This is standard SwiftUI behaviour in iOS 15, as it implements by default the recommendations from Apple’s Human Interface Guidelines, which says tab bars should use filled variants of SF Symbols, while sidebars on iPad should use the outline variant.
The effect is achieved by iOS automatically applying the .symbolVariants environment value, as noted in the symbol variants documentation:
SwiftUI sets a variant for you in some environments. For example, SwiftUI automatically applies the fill symbol variant for items that appear in the content closure of the swipeActions(edge:allowsFullSwipe:content:) method, or as the tab bar items of a TabView.
If you absolutely want to get rid of the fill mode, it’s deliberately made tricky but not impossible. You have to override the supplied \.symbolVariants environment variable directly on the Label element, inside your tabItem declaration:
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
.environment(\.symbolVariants, .none)
}
Using the .symbolVariants(.none) modifier, or trying to set the environment value higher up the view graph, won’t work.
Now that you see how to override the effect, I would still advise using the filled forms in the tab bar. Given that the tab bar no longer has a background colour difference from the rest of the page in many cases, the extra visual weight given to tab items by use of the filled variant lends the right amount of visual weight to those elements.
As the title says, is there any way I can detect (e.g. using a #State variable) when either any context menu is open, or the context menu of a specific view is open?
As a basic idea, I would like to print something if it is open. This does not work:
.contextMenu {
print("open")
}
This also does not seem to work:
.contextMenu {
EmptyView()
.onAppear {
print("open")
}
}
How could i make this work?
Edit: Why i think its even possible to do it or at least possible to make it look like its possible: On instagram, one can see individual posts as a square only. However using long-press, a context menu opens, and now the post shape is different, but even more there is also a small title above it.. How would one do that? Did they modify the view when the context menu open or is the grid view the post is in before just hiding those details (true image shape + image title) but they are rendered already?
Screenshots:
A possible approach is to use simultaneous gesture for this purpose, like
Text("Demo Menu")
.contextMenu(menuItems: {
Button("Button") {}
})
.simultaneousGesture(LongPressGesture(minimumDuration: 0.5).onEnded { _ in
print("Opened")
})
Tested with Xcode 13.2 / iOS 15.2
Is it possible to include a TabView in SwiftUI that doesn’t change views? I need a bottom menu bar that has 4 items in, but these items do not all need to move to a new view. Can I change the expected behaviour of TabView and utilise the buttons it provides or do I need to just make my own?
If you're using the newest beta (2020), you could use a toolbar.
On iOS you can set the placement of the a ToolbarItem as the bottom bar, and make look similar to a bottom tab bar. Back in UIKit you would probably have used a toolbar as well, since TabBars are associated with navigation.
Anyway, here's an example:
HStack {
ForEach(1..<5) { number in
Text("\(number)")
}
}
.toolbar(items: {
ToolbarItem(placement: .bottomBar) {
Button("Test", action: {})
}
})
Add a toolbar modifier to your view, then add the items with whatever content you want. Since the ToolbarItem uses a view builder, you can give it any view.
If you want multiple buttons spread out nicely, replace the Button inside the ToolbarItem with an HStack and have multiple buttons/spacers/whatever you need to get the layout you want.
Note: the .bottomBar placement might not be available on all platforms
I am trying to add an image next to the hamburger menu in my app. I am using a master detail page and it renders fine in ios and android. I tried using setting the icons for the detail pages. but the icons never showed. How do I achive this. I am looking to add an image similar to the amazon app.
I checked out this app on my phone and it uses a lot of custom constructions that aren't supported by out of the box Xamarin Forms controls. Something like the back arrow next to the hamburger menu is not a standard thing (on iOS at least). Also looking at the actual menu that the hamburger button triggers it becomes clear that its not an out of the box hamburger menu. Theirs pops over the content instead of sliding it out of view as the built-in one does.
More than likely they implemented their own hamburger menu and navigation structure which gave them the freedom to add buttons next to it. If you want to achieve this with out of the box controls you will most likely need custom renderers for each platform to create a replica of this navigation structure.
What is built-in in Xamarin Forms is that you can set the page title to an image instead of text by using the NavigationPage.SetTitleIcon method, which could be used to achieve what you want:
public class MyPage : NavigationPage
{
public MyPage ()
{
var myContentPage = new MyContentPage (Color.White);
this.Push (myContentPage);
var s = "icon.png";
NavigationPage.SetTitleIcon (myContentPage, s);
}
}
Even then, this is limited in functionality. If you want to fiddle with the alignment of the image e.g. you would also need to resort to a custom renderer.