center an indicator view in an alertcontroller programmatically - ios

I am trying to center an activity indicator in an alert controller programmatically but am not seeing the expected outcome.
Attempt:
import NVActivityIndicatorView
public func displayActivityAlertWithCompletion(ViewController: UIViewController, pending: UIAlertController, completionHandler: #escaping ()->())
{
//create an activity indicator
let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))
//indicator.clipsToBounds = true
indicator.type = .ballScaleMultiple
indicator.autoresizingMask = \[.flexibleWidth, .flexibleHeight\]
indicator.color = UIColor(rgba: Palette.loadingColour)
//add the activity indicator as a subview of the alert controller's view
pending.view.addSubview(indicator)
indicator.isUserInteractionEnabled = false
// required otherwise if there buttons in the UIAlertController you will not be able to press them
indicator.startAnimating()
ViewController.present(pending, animated: true, completion: completionHandler)
}

The problem you are facing lies in this line:
let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))
At this point your pending alert controller is not yet presented, and it's frame is not updated.
You will have to update the frame of the indicator after the alert controller was presented, so for example you can do the following.
Replace this line:
ViewController.present(pending, animated: true, completion: completionHandler)
With this:
ViewController.present(pending, animated: true, completion: {
// update frame here:
indicator.frame = CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50)
// and manually call completionHandler:
completionHandler()
})

Related

show badge on bar button item with action

I have a bar button item on my view controller which is showing a popover view, and I have an extension to show badges on any button,
I tried to show the badges on the icon but it shows me another view, and I want to show the badges on my bar button item,
I tried this code
func addBadge(itemvalue: String) {
let bagButton = BadgeButton()
bagButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
bagButton.tintColor = UIColor.darkGray
bagButton.setImage(UIImage(named: "comment")?.withRenderingMode(.alwaysTemplate), for: .normal)
bagButton.badgeEdgeInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 15)
bagButton.badge = itemvalue
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: bagButton)
}
my popover button code
#IBAction func showPopoverButtonAction(_ sender: Any) {
//get the button frame
/* 1 */
let button = sender as? UIButton
let buttonFrame = button?.frame ?? CGRect.init(x: -20, y: -320, width: 200, height: 400)
/* 2 */
//Configure the presentation controller
guard let popoverContentController = self.storyboard?.instantiateViewController(withIdentifier: "PopOverViewController") as? PopOverViewController else { return }
popoverContentController.modalPresentationStyle = .popover
popoverContentController.dpostID = self.postIdm
popoverContentController.dpostTitle = self.postTitlem
popoverContentController.duserPhone = self.muserPhone
popoverContentController.delegate = self
/* 3 */
if let popoverPresentationController = popoverContentController.popoverPresentationController {
popoverPresentationController.permittedArrowDirections = .up
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = buttonFrame
popoverPresentationController.delegate = self
// if let popoverController = popoverContentController {
//
// }
present(popoverContentController, animated: true, completion: nil)
}
}
currently it is showing like this!
enter image description here
but I want the badges to be on my bar button not new button!
to clarify: the new bar button with badge is generated by the code in the question, and the comment button is mybutton which I want to show the badges on.
popover button is the button that I want to show the badges on instead of the generated button from the code

Why button appears only on the second attempt?

I'm trying to add a function that will show the close button in my custom alert view.
When I call it for the first time, only an empty area appears that does not contain a button (no color, no text and no pressing). When you call again - everything works as it should.
It does not depend on the parameter animated, in both cases it works the same.
My dialogView is a my custom UIView. I don't use UIAlertController
What could be the problem?
initial view after the first attempt second attempt
GIF call func by click
func showCloseButton(text: String, animated: Bool){
let dialogViewHeight = self.dialogView.frame.height + 50 + 1
let button = UIButton(type: .roundedRect)
button.backgroundColor = .red
button.frame.origin = CGPoint(x: 0, y: dialogViewHeight)
button.frame.size = CGSize(width: self.dialogView.frame.width, height: 50)
button.setTitle(text, for: .normal)
button.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
let separatorLineView = UIView()
separatorLineView.frame.origin = CGPoint(x: 0, y: self.dialogView.frame.height)
separatorLineView.frame.size = CGSize(width: dialogView.frame.width, height: 1)
separatorLineView.backgroundColor = UIColor.groupTableViewBackground
dialogView.addSubview(separatorLineView)
if animated {
animateAdjustDialogView(height: dialogViewHeight){
Logger.Log("completion did")
self.dialogView.addSubview(button)
}
} else {
Logger.Log("button.frame.origin = \(button.frame.origin)")
Logger.Log("button.frame.size = \(button.frame.size)")
Logger.Log("button.title = \(button.titleLabel)")
self.dialogView.frame.size = CGSize(width: self.dialogView.frame.width, height: dialogViewHeight)
self.dialogView.addSubview(button)
}
}
private func animateAdjustDialogView(height: CGFloat, completion: (()->Void)?){
UIView.animate(withDuration: 1.0, animations: {
self.dialogView.frame.size = CGSize(width: self.dialogView.frame.width, height: height)
self.layoutIfNeeded()
}) { (finished) in
Logger.Log("finished = \(finished)")
if finished {
Logger.Log("completion run")
completion?()
}
}
}
Button frame is causing the issue -
button.frame.origin = CGPoint(x: 0, y: dialogViewHeight)
Where
let dialogViewHeight = self.dialogView.frame.height + 50 + 1
That means, button goes beyond dialogView frame.
So replace
button.frame.origin = CGPoint(x: 0, y: dialogViewHeight)
With
button.frame.origin = CGPoint(x: 0, y: dialogViewHeight - 50) // Height of the Button.
Let me know if you are still having any issue.

Swift 3 - Add Text to UIView Pop up

I want to display a pop up with some fixed text in it.
I found this for the pop up.
// Define a view
var popup:UIView!
func showAlert() {
// customise your view
popup = UIView(frame: CGRect(x: 100, y: 200, width: 200, height: 200))
popup.backgroundColor = UIColor.redColor
// show on screen
self.view.addSubview(popup)
// set the timer
Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.dismissAlert), userInfo: nil, repeats: false)
}
func dismissAlert(){
if popup != nil { // Dismiss the view from here
popup.removeFromSuperview()
}
}
I can't seem to add a label in the showAlert() and display it.
I tried calling a seperate function in showAlert that gets the label text, that works but it wont dismiss.
How can I add a text/string/Label to the pop up in the showAlert function itself? I want to use UIView itself, not AlertController.
You can try
popup = UIView(frame: CGRect(x: 100, y: 200, width: 200, height: 200))
let lb = UILabel(frame: CGRect(x: 100, y: 200, width: 200, height: 200))
lb.text="anything"
popup.backgroundColor = UIColor.redColor
// show on screen
self.view.addSubview(popup)
popup.addSubview(lb)
lb.center = popup.center

UIActivityIndicatorView dialog over view

In my app I'm using a custom UIActivityIndicator view (this) and it works great.
I have an UITableView and I want the indicator over the tableview on loading data. To solve the problem I have created an empty view with a background above all and when I need to start indicator's animation I simply hide tableview and show the empty view + the indicator.
The result is this:
I saw somewhere that I can use instead something like this:
How can I do?
Thanks in advance.
You could try adding a translucent Black view over the Table View and put the custom activity indicator code as a subview in the Black view.
let aBlackView = UIView(frame: CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height))
aBlackView.backgroundColor = UIColor.blackColor()
aBlackView.alpha = 0.75 // Change the alpha depending on how much transparency you require
let aMainWindow = UIApplication.sharedApplication().delegate!.window
aMainWindow!!.addSubview(aBlackView)
/* Enter you code for NVActivityIndicatorViewable here */
aBlackView.addSubview(/* NVActivityIndicatorViewable */)
Once you are done with your request, you can remove the Black view by calling this code:
aBlackView.removeFromSuperview()
I created a activity showing screen . I used in every where in my project.
//ProgressBarNotification.swift
import Foundation
import UIKit
class ProgressBarNotification {
internal static var strLabel = UILabel()
internal static var messageFrame = UIView()
internal static var activityIndicator = UIActivityIndicatorView()
internal static func progressBarDisplayer(msg:String,indicator:Bool ){
let view1 = UIApplication.sharedApplication().delegate?.window!!.rootViewController?.view
view1?.userInteractionEnabled = false
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 200, height: 50))
strLabel.text = msg
strLabel.textColor = UIColor.whiteColor()
messageFrame = UIView(frame: CGRect(x: view1!.frame.midX - 90, y: view1!.frame.midY - 25 , width: 180, height: 50))
messageFrame.layer.cornerRadius = 15
messageFrame.backgroundColor = UIColor(white: 0, alpha: 0.7)
if indicator {
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.White)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
activityIndicator.startAnimating()
messageFrame.addSubview(activityIndicator)
}
messageFrame.addSubview(strLabel)
view1!.addSubview(messageFrame)
}
internal static func removeProgressBar() {
let view1 = UIApplication.sharedApplication().delegate?.window!!.rootViewController?.view
_ = view1?.subviews.filter({ (view) -> Bool in
if view == ProgressBarNotification.messageFrame {
view.removeFromSuperview()
}
return false
})
ProgressBarNotification.messageFrame.removeFromSuperview()
view1?.userInteractionEnabled = true
}
deinit{
}
}
Usage
//To start Loader
ProgressBarNotification.progressBarDisplayer("Loading", indicator: true)
//Stop
ProgressBarNotification.removeProgressBar()

Popover presentation in iOS 9

I want to Display a viewController in Popover in iPad . But this line
self.poc = UIPopoverController(contentViewController: sec) deprected in iOS 9
let sec:PopView=PopView(nibName:"PopView",bundle:nil)
self.poc = UIPopoverController(contentViewController: sec)
poc!.delegate=self
self.poc!.presentPopoverFromRect( CGRect(x: 150, y: 222, width: 50, height: 30), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Right, animated: true)
You need to use UIPopoverPresentationController :
let sec = UIViewController(nibName:"PopView",bundle:nil)
sec.modalPresentationStyle = .Popover
if let secPopoverPresentationController = sec.popoverPresentationController{
secPopoverPresentationController.sourceView = yourSourceView
secPopoverPresentationController.permittedArrowDirections = [.Any]
//Optionally configure other things like sourceRect , delegate ...
}
presentViewController(sec, animated: true, completion: nil)
Hope this helps.

Resources