I have the following code that generates a context menu when a user taps on a uibarbutton in a navigation bar:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGreen
title = "Hello"
let scribbleAction = UIAction(title: "Scribble", image: UIImage(systemName: "scribble"), state: .on, handler: { (_) in })
let textAction = UIAction(title: "Typing", image: UIImage(systemName: "textformat"), state: .off, handler: { (_) in })
let clockAction = UIAction(title: "Show Clock", image: UIImage(systemName: "clock"), state: .off, handler: { (_) in })
let calendarAction = UIAction(title: "Date Last Used", image: UIImage(systemName: "calendar"), state: .off, handler: { (_) in })
var showAsActions: [UIAction] {
return [
clockAction, calendarAction
]
}
var showAsMenu : UIMenu {
return UIMenu(title: "Show As", image: UIImage(systemName: "questionmark.circle.fill"), identifier: .none, children: showAsActions)
}
let menu = UIMenu(title: "",
image: nil,
identifier: nil,
options: [],
children: [showAsMenu, scribbleAction, textAction])
let barButtonRight = UIBarButtonItem(title: "Sort", image: UIImage(systemName: "ellipsis.circle.fill"), primaryAction: nil, menu: menu)
navigationItem.rightBarButtonItems = [barButtonRight]
}
}
This all works and produces the following when a user taps on the button in the navigation bar:
Tapping on the first menu item yields the desired effect:
But at times, I need to be able to also mark the first menu item (which is a submenu item) with a checkmark. I can't work out how to do this and have searched on Stackoverflow as well as the Apple Developer Forums etc and can't work it out. Any suggestions would be greatly appreciated.
Related
I have an app where you can either take a profile picture, or choose from library, but i want one more option where you can see what profile picture you are using and choosing that option would make your profile picture pop out.
public func present(from sourceView: UIView, didSelect image: UIImage?) {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
if self.isMediaTypeVideo {
if let action = self.action(for: .camera, title: "Take Video") {
alertController.addAction(action)
}
if let action = self.action(for: .photoLibrary, title: "Choose video") {
alertController.addAction(action)
}
}
else {
if let action = self.action(for: .camera, title: "Take a Picture") {
alertController.addAction(action)
}
if let action = self.action(for: .photoLibrary, title: "Choose a Picture") {
alertController.addAction(action)
}
if let action = self.action(for: ., title: "View Picture") {
alertController.addAction(action)
}
}
Here is my code I got how to do the first two options of "taking a picture" and "choosing from library" but how can i get a third option to look an enlarge version of your current profile picture?
what can i put for the last "View Picture" option on self.action(for:__, title: "View Picture"
I have a protocal function called didselect image that shows what image there is.
extension UserAccountSettingsViewController: ImagePickerDelegate {
func didSelect(image: UIImage?) {
if let image = image {
self.startImageLoader()
if UserDefaults.standard.string(forKey: "userImageLastUpdated") == "" {
uploadFile(withImage: image)
} else {
removeFile(upload: true, withImage: image)
}
}
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am trying to implement based on ActionSheet button click to show selected button title on main viewcontroller UILabel. Here, below code I am using but the label title not updating based on actionsheet button click.
The issue happening by for loop execution. UILabel.text not changing before last For Loop execution. how to handle and fix it?
ActionSheet
#IBAction func ClickAction(_ sender: Any) {
let actionSheetAlertController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for title in self.titleData {
let action = UIAlertAction(title: title.status, style: .default) { (action) in
print("Title: \(title.status)")
print("Title: \(title.id)")
self.resultTitle.text = title.status // not updating here.
let icon = UIImage.init(named: title.icon)
action.setValue(icon, forKey: "image")
action.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
actionSheetAlertController.addAction(action)
}
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheetAlertController.addAction(cancelActionButton)
self.present(actionSheetAlertController, animated: true, completion: nil)
}
Getting Output
Your issue not occured in my machine. Please restart your machine, maybe problem will resolve.
You need to make the checks with action title not with the id. So, here is you solution that is working fine:
struct ActionOption {
var id: String
var title: String
var icon: UIImage?
static func getAll() -> [ActionOption] {
let titleData = ["Red", "Green", "Yellow"]
var all: [ActionOption] = []
for (idx, ttl) in titleData.enumerated() {
all.append(ActionOption(id: "\(idx)", title: ttl, icon: nil))
}
return all
}
}
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var titleData: [ActionOption] = []
override func viewDidLoad() {
super.viewDidLoad()
self.titleData = ActionOption.getAll()
}
#IBAction func changeAction(_ sender: Any) {
let actionSheetAlertController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for title in self.titleData {
let action = UIAlertAction(title: title.title, style: .default) { (action) in
switch (action.title ?? "") { // you need to vhange your code here
case "Red" :
self.imageView.backgroundColor = UIColor.red
case "Green" :
self.imageView.backgroundColor = UIColor.green
case "Yellow" :
self.imageView.backgroundColor = UIColor.yellow
default : self.imageView.backgroundColor = UIColor.black
}
}
action.setValue(title.icon, forKey: "image")
action.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
actionSheetAlertController.addAction(action)
}
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheetAlertController.addAction(cancelActionButton)
self.present(actionSheetAlertController, animated: true, completion: nil)
}
}
You need to make some changes in you switch statement, use the parameter closure for deciding the desired action to perform. As these closure will call when the action being perform and that time title for loop object will not be present/available for being used.
Result As of Code:
Just put self.resultTitle.text = title.status inside DispatchQueue.main.async { }
#IBAction func ClickAction(_ sender: Any) {
let actionSheetAlertController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for title in self.titleData { // I thik this is the plm
let action = UIAlertAction(title: title.status, style: .default) { (action) in
print("Title: \(title.status)")
print("Title: \(title.id)")
DispatchQueue.main.async {
self.resultTitle.text = title.status
}
}
let icon = UIImage.init(named: title.icon)
action.setValue(icon, forKey: "image")
action.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
actionSheetAlertController.addAction(action)
}
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
actionSheetAlertController.addAction(cancelActionButton)
self.present(actionSheetAlertController, animated: true, completion: nil)
}
I have a UIAlertController implementation with two actions:
let alert = UIAlertController(title: "Add your photo", message: "", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Add Later", style: .cancel) { (action) -> Void in }
let uploadAction = UIAlertAction(title: "Upload", style: .default) { (action) -> Void in }
alert.addAction(cancelAction)
alert.addAction(uploadAction)
present(alert, animated: true, completion: nil)
Now, I want to add an image (at center) below the title, with the two actions still being aligned as in the picture. What I have tried to do is create a UIImageView and add it to alertcontroller as:
let image = UIImage(named: "myimage.png")
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: alert.view.frame.width/2, y: alert.view.frame.height/2, width: 50, height: 50)
alert.view.addSubview(imageView)
But I cannot get it at the center of the alert. Is this the correct way? Or is there some other easy method to achieve this? How can I achieve this?
Use the following extension which allows to fully customise UIAlertController:-
extension UIAlertAction{
#NSManaged var image: UIImage?
convenience init(title: String?, style: UIAlertActionStyle,image : UIImage?, handler: ((UIAlertAction) -> Swift.Void)? = nil ){
self.init(title: title, style: style, handler: handler)
self.image = image
}
}
I have programmatically created a navigation bar with a left and right bar button items. On clicking the right UIBarButtonItem the action sheet is presented,and then if i click left button,the action sheet persists. It does not dismiss. But if I tap anywhere else in the view controller the actionsheet is dismissed. The issue is only for iPad. This is the function called on the right bar button click.
func showActionButtons()
{
actionSheetController = UIAlertController(title: Constants.kPleaseSelect, message: nil, preferredStyle: .actionSheet)
let cancelActionButton = UIAlertAction(title: Constants.kCancel, style: .cancel) { action -> Void in
}
actionSheetController.addAction(cancelActionButton)
let cameraActionButton = UIAlertAction(title: "Camera", style: .default) { action -> Void in
//open camera
self.checkCamera()
}
actionSheetController.addAction(cameraActionButton)
let galleryActionButton = UIAlertAction(title: "Gallery", style: .default) { action -> Void in
//open gallery
self.checkGallery()
}
actionSheetController.addAction(galleryActionButton)
actionSheetController.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
self.present(actionSheetController, animated: true, completion: nil)
}
//Set RightBar Item with image
private func setRightBarSelectAllItem() {
let image = UIImage(named: "ic_nav_select_all")?.withRenderingMode(.alwaysOriginal)
let backItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(onBtnSelectAll(_:)))
self.navigationItem.rightBarButtonItem = backItem
}
//IBAction
#IBAction func onBtnSelectAll(_ sender: UIBarButtonItem) {
showActionSheet(sender: sender)
}
//ActionSheet
private func showActionSheet(sender : UIBarButtonItem) {
let alt = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let select = UIAlertAction(title: "Select", style: .default) { (act) in
}
let selectAll = UIAlertAction(title: "Select All", style: .default) { (act) in
}
let deleteAll = UIAlertAction(title: "Delete All", style: .destructive) { (act) in
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (act) in
}
alt.addAction(select)
alt.addAction(selectAll)
alt.addAction(deleteAll)
alt.addAction(cancel)
alt.popoverPresentationController?.barButtonItem = sender
self.present(alt, animated: true, completion: nil)
}
i want to create one tab bar from storyboard and i create it but when click on tab bar at that time image is not showing and some images i want tab bar like
and i got this
When i click on any tab bar item its display like
Here is my code that i use in profile view controller
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarStyle = .default
self.tabBarController?.tabBar.isHidden = false
UITabBar.appearance().tintColor = UIColor.init(patternImage: UIImage.init(named: "ic_home_tab_profile_sel.png")!)
// Do any additional setup after loading the view.
}
}
Any help can be appreciate .
Thank You in advance.
I suggest to use ESTabBarControllerExample https://github.com/eggswift/ESTabBarController to making that kind of custom TabbarController.First Download the ESTabbarControllerExample from github. We need to use some class letter on. Let me explain how to use step by step:
First Install CocoaPods
1 Open terminal and cd ~ to your project directory
2 Run the command - pod init
3 Your podfile should be use with - pod
"ESTabBarController-swift" and save it
4 And install it with command pod install
Open project file of .xcworkspace extension
1 In project we need to add Content all swift class and pop.framework
2 Don't add pop.framework using add File to. you must be add from Framework and add Others.
3 In Content folder's all file import ESTabBarController_swift
StoryBord Stuff
1 Add navigation Controller ane also add ExampleNavigationController from the example code of EST demo. (You can add your own too) but make sure you set its Class of navigation custom swift class.
Code Stuff at AppDelegate.swift
You need to do following code in side didFinishLaunchingWithOptions
let tabBarController = ESTabBarController()
tabBarController.delegate = self
tabBarController.title = "Irregularity"
tabBarController.tabBar.shadowImage = UIImage(named: "transparent")
tabBarController.tabBar.backgroundImage = UIImage(named: "background_dark")
tabBarController.shouldHijackHandler = {
tabbarController, viewController, index in
if index == 2 {
return true
}
return false
}
tabBarController.didHijackHandler = {
[weak tabBarController] tabbarController, viewController, index in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
let alertController = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet)
let takePhotoAction = UIAlertAction(title: "Take a photo", style: .default, handler: nil)
alertController.addAction(takePhotoAction)
let selectFromAlbumAction = UIAlertAction(title: "Select from album", style: .default, handler: nil)
alertController.addAction(selectFromAlbumAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
tabBarController?.present(alertController, animated: true, completion: nil)
}
}
let v1 = ExampleViewController()
let v2 = ExampleViewController()
let v3 = ExampleViewController()
let v4 = ExampleViewController()
let v5 = ExampleViewController()
v1.tabBarItem = ESTabBarItem.init(ExampleIrregularityBasicContentView(), title: "Home", image: UIImage(named: "home"), selectedImage: UIImage(named: "home_1"))
v2.tabBarItem = ESTabBarItem.init(ExampleIrregularityBasicContentView(), title: "Find", image: UIImage(named: "find"), selectedImage: UIImage(named: "find_1"))
v3.tabBarItem = ESTabBarItem.init(ExampleIrregularityContentView(), title: nil, image: UIImage(named: "photo_verybig"), selectedImage: UIImage(named: "photo_verybig"))
v4.tabBarItem = ESTabBarItem.init(ExampleIrregularityBasicContentView(), title: "Favor", image: UIImage(named: "favor"), selectedImage: UIImage(named: "favor_1"))
v5.tabBarItem = ESTabBarItem.init(ExampleIrregularityBasicContentView(), title: "Me", image: UIImage(named: "me"), selectedImage: UIImage(named: "me_1"))
tabBarController.viewControllers = [v1, v2, v3, v4, v5]
let navigationController = ExampleNavigationController.init(rootViewController: tabBarController)
tabBarController.title = "Example"
self.window?.rootViewController = navigationController
return true
Add Images for Tabbar items and other that you want to use for in Assets.
Hope that helps for you.
Sample Project: https://github.com/nitingohel/CustomTabCenterBig