How to Add UIToolbar with two button in UIPickerView(swift 2.0)? - ios

I would like to add two UIButtons in the UIPickerView (on bottom of it). Please take a look at the Cancel and Done buttons in this image:
Here My code Upload:-
class DatePicker{
var containerView = UIView()
var datePicker = UIView()
var datePickerView = UIDatePicker()
var toolBar = UIToolbar()
internal class var shared: DatePicker {
struct Static {
static let instance: DatePicker = DatePicker()
}
return Static.instance
}
internal func showProgressView(view: UIView) {
containerView.frame = view.frame
containerView.center = view.center
containerView.backgroundColor = UIColor(hex: 0xffffff, alpha: 0.3)
datePickerView.datePickerMode = .Date
datePicker.frame = CGRectMake(0, 0, 250, 250)
datePicker.center = view.center
datePicker.backgroundColor = UIColor(hex: 0x444444, alpha: 0.7)
datePicker.clipsToBounds = true
datePicker.layer.cornerRadius = 10
datePickerView.setValue(UIColor.whiteColor(), forKeyPath: "textColor")
datePickerView.frame = CGRectMake(0, 0, 250, 250)
datePicker.addSubview(datePickerView)
containerView.addSubview(datePicker)
view.addSubview(containerView)
}
internal func hideProgressView() {
containerView.removeFromSuperview()
}
}
How can i get UIToolbar And Two Button?

I would recommend making a .xib with the toolbar and picker view in it. Put two bar buttons on the bar and put a bar button spacer in between them.
Link on how to use a xib
You can make the animation of it appearing look great if you start its frame off screen and use this function to move it on screen.
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .CurveEaseInOut, animations: {
if viewToMove != nil {
viewToMove!.frame.origin.y/*orX*/ = onScreenPosition
} else {
"sidePanel == nil"
}
}, completion: completion)
usingSpringWithDamping can be set to 1 if you don't want any bounce in animation. If this is for an iPhone, i would recommend making the initial frame equal to something like
CGRectMake(0, UIScreen.mainScreen().bounds.height, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height/2)
and then the view to move line would become
viewToMove!.frame.origin.y = UIScreen.mainScreen().bounds.height/2
using the previous function to bring it on screen and
viewToMove!.frame.origin.y = UIScreen.mainScreen().bounds.height
to move it off screen. You can access the buttons of the xib in a few different ways, but I recommend using a delegate.
Here is a guide to them.
If you are not familiar with them, I would become familiar, because they are very useful! If you have any questions don't hesitate to ask!

Related

Adding GestureRecognizer to UIView won't trigger action

I have no idea why this gesture recognizer is not working as intended:
class SlideInMenuLauncher: NSObject, UITableViewDelegate, UITableViewDataSource {
fileprivate let dimmerView = UIView()
fileprivate let tableView: UITableView = {
let tbv = UITableView(frame: .zero)
return tbv
}()
fileprivate let resourceArray: [Content]
weak var delegate: SlideInMenuDelegate?
let cellIdentifier = "SlideInMenuTableViewCell"
init(withContentArray contentArray: [Content]) {
resourceArray = contentArray
super.init()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier)
}
func showMenu() {
if let window = UIApplication.shared.keyWindow {
dimmerView.backgroundColor = UIColor(white: 0, alpha: 0.5)
dimmerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dismissMenu)))
dimmerView.isUserInteractionEnabled = true
window.addSubview(dimmerView)
window.addSubview(tableView)
let height: CGFloat = 200
let y = window.frame.height - height
tableView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
dimmerView.frame = window.frame
dimmerView.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.dimmerView.alpha = 1
self.tableView.frame = CGRect(x: 0, y: y, width: self.tableView.frame.width, height: self.tableView.frame.height)
}, completion: nil)
}
}
func dismissMenu() {
UIView.animate(withDuration: 0.5) {
self.dimmerView.alpha = 0
if let window = UIApplication.shared.keyWindow {
self.tableView.frame = CGRect(x: 0, y: window.frame.height, width: self.tableView.frame.width, height: self.tableView.frame.height)
}
}
}
I've put a breakpoint in the dismissMenu function but it is never triggered. Perhaps my tired eyes (and mind) missed something simple?
Here I am adding the code where I actually call this class in case something is wrong there:
///Some other VC
let slideInMenuLauncher = SlideInMenuLauncher(withContentArray: [content])
slideInMenuLauncher.showMenu()
I would expect that to give a compiler error. You're missing the #objc declaration on your dismissMenu() function.
I added a view to a view controller in a storyboard and used a small variant of your code and it responds to taps just fine. Thus my guess is that there's something wrong with the way you're adding your views to the view controller.
EDIT:
I know what the problem is: If you set a view's alpha to 0 it stops responding to taps. Try setting the view's opaque flag to false and setting it's background color to clearColor.
Here's the code from the test project I created:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tapView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
tapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
tapView.isUserInteractionEnabled = true
}
#objc func handleTap() {
print("You tapped on the view")
}
}
Can you try instead of this:
window.addSubview(dimmerView)
window.addSubview(tableView)
Do this:
window.addSubview(dimmerView)
window.addSubview(tableView)
window.bringSubviewToFront(dimmerView)
Try use following code:
let tapGes = UITapGestureRecognizer(target: self, action:#selector(dismissMenu))
tapGes.delegate = self
dimmerView.addGestureRecognizer(tapGes)
Hope it help you!
I think your problem is here:
dimmerView.alpha = 0
If I remember correctly, views that have their alpha set to 0 don't get touches. Try setting is to something like 0.5 just to see if it works, and then dial it back to a smaller value that's still greater than 0.
So I found the problem thanks to this post. When I was using the slideInMenuLauncher class elsewhere, I was not saving it to a strong reference or anything, so once I moved out of the scope of the function where I created the menu, the SlideInMenuLauncher object I used to create the dimmerView and tableView disappeared (despite still being able to see the views). Once I tapped the dimmerView the gesture recognizer sent a message to an object that no longer existed.
Setting the object to a strong property fixed the issue.

Add UIView over UIViewImage. Users can zooming image

I tried to add UIView over my UIImage. But it doesn't work for me.
When I reduce and increase my image, UIView moved down and doesn't cover completely my image.
I use double click for zooming.
#objc func doubleTap(gestureRecognizer: UITapGestureRecognizer) {
if self.productScrollView.zoomScale == 1 {
self.productScrollView.zoom(to: self.zoomRectForScale(scale: self.productScrollView.maximumZoomScale, center: gestureRecognizer.location(in: gestureRecognizer.view)), animated: true)
} else {
self.productScrollView.setZoomScale(1, animated: true)
}
}
I tried to use these codes, but it doesn't work for me.
first:
let tintView = UIView()
tintView.backgroundColor = UIColor(white: 0, alpha: 0.5)
tintView.frame = CGRect(x: 0, y: 0, width: imageView.frame.width,
height: imageView.frame.height)
imageView.addSubview(tintView)
Second:
let tintView = UIView()
tintView.backgroundColor = UIColor(white: 0, alpha: 0.5)
tintView.translatesAutoresizingMaskIntoConstraints = false
imageView.addSubview(tintView)
NSLayoutConstraint.activate([
tintView.bottomAnchor.constraint(equalTo: imageView.bottomAnchor),
tintView.leadingAnchor.constraint(equalTo: imageView.leadingAnchor),
tintView.trailingAnchor.constraint(equalTo: imageView.trailingAnchor),
tintView.topAnchor.constraint(equalTo: imageView.topAnchor),
])
also, I tried to add on storyboard, but it also doesn't work for me.
Does anyone have ideas or suggestions?
Try to add your UIView to the main view of your viewController instead of UIImageView and set constraints to the imageView

Swift. Flip animation. FromView is not displayed

I've wrote this code to create a simple flip animation:
func frontView (view:UIView) ->UIView {
var frontView: UIView
frontView = UIView()
frontView.frame = view.frame
frontView.center = CGPoint(x: 0, y: 0)
return frontView
}
func backView (view:UIView) ->UIView {
var backView: UIView
backView = UIView()
backView.frame = view.frame
backView.backgroundColor = UIColor.redColor()
backView.center = CGPoint(x: view.frame.width/2, y: 0)
view.addSubview(backView)
return backView
}
func flipViewAnimation (viewToAnimate: UIView) {
var animationOption = self.animationOption
var duration = self.duration
UIView.transitionFromView(backView(viewToAnimate), toView: frontView(viewToAnimate), duration: duration, options: animationOption, completion: nil)
//
}
As a viewToAnimate I use views with labels and imageViews inside, which I've created in AutoLayout. The result I'm trying to achieve more or less should look like this. First I see views filled with color, then they flip and show the content inside (labels and ImageViews).
But it works in a different way. Views appear already with content (labels and ImageViews) then just flip and again show the same content.
I've created each view programmatically and it works very well for me now.

Present UIView over Apple Statusbar

I want to cover the statusbar with a view like the following code shows. I have read a lot that this needs to be done in an separate(?) window that is on the same windows layer as the statusbar but I just don't get it to work.
I tried this (first code)
Display UIView Above Apple Status Bar in iOS 8
but my self.view.window? is nil
Trying to create a new UIWindow XCODE wants a rootViewController which I would have to fake... IMHO That cannot be the right way
Here is my code:
class GroupSelectionTVC: UITableViewController
{
override func viewDidLoad()
{
// Toast
let frame = CGRectMake(0, -20, self.view.frame.width, 20)
let message = UILabel(frame: frame)
message.backgroundColor = UIColor.blackColor()
message.text = "Testing"
message.textAlignment = NSTextAlignment.Center
message.textColor = UIColor.darkGrayColor()
self.view.addSubview(message)
UIView.animateWithDuration(1.0, animations: {
message.frame = CGRectMake(0, 0, self.view.frame.width, 20)}, completion:
{
(value: Bool) in UIView.animateWithDuration(1.0, delay: 2.0, options: nil, animations: {message.frame = CGRectMake(0, -20, self.view.frame.width, 20)}, completion:
{
(value: Bool) in message.removeFromSuperview()
}
)
}
)
I would recommend you to use CRToast. It's a framework for exactly your kind of problem. So you don't have to worry about UIViews etc. It's written in Objective-C but you can easily use it in a Swift project.

Having an issue animating certain elements UIView will excluding others

In my code, I've correctly moved the UITextfield into view when the keyboard pops up. However, I've struggled to create another animation that acts only on the UIImageView as this current solution permanently offsets the logo in the UIImageView.
var logoImage:UIImageView!
var logoImageX:CGFloat = 85
var logoImageY:CGFloat = 35
// Logo Code
let logo:UIImage = UIImage(named:"color-logo.png")
let logoHeight:CGFloat = 150
let logoWidth:CGFloat = logoHeight
logoImage = UIImageView(image:Logo)
logoImage.frame = CGRectMake(logoImageX,logoImageY,logoWidth, logoHeight)
self.view.insertSubview(logoImage, atIndex: 1)
// Keyboard Auto Scroll
func textFieldDidBeginEditing(textField: UITextField!) {
self.animateTextField(textField, up: true)
self.animateWithDuration(true)
}
func textFieldDidEndEditing(textField: UITextField!) {
self.animateTextField(textField, up: false)
self.animateWithDuration(false)
}
func animateTextField(textField:UITextField,up: Bool){
let movementDistance:Int = -100
let movementDuration:NSTimeInterval = 0.25
var movement = CGFloat(Int((up ? movementDistance : -movementDistance)))
UIView.beginAnimations("animateTextField", context:nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
Here's the function for the UIImageView:
//Logo (UIImageView) Scroll
func animateWithDuration(up:Bool){
let logoMovementDuration = 0.25
let logoMovementDistance:Int = 20
var logoMovement = CGFloat(Int((up ? logoMovementDistance : -logoMovementDistance + (logoImageY))))
UIView.beginAnimations("animateWithDuration", context:nil)
UIView.setAnimationDuration(logoMovementDuration)
logoImage.frame = CGRectMake(logoImageX,logoMovement,logoImage.frame.size.width,logoImage.frame.size.height)
UIView.commitAnimations()
}
I've found a solution by creating multiple UIViews, or in my case 3 specifically.
The code looks like this, depending on what you want to achieve, segregated into different groups in order to apply animations to each of them (these are declared outside of the viewDidLoad() to make them publicly accessible):
var otherView = UIView(frame: UIScreen.mainScreen().bounds)
var logoImageView = UIView(frame:CGRect(x: 0, y: 0, width: xx, height: xx))
var resultView = UIView(frame:CGRect(x: 0, y: 0, width: xx, height: xx))
After which, I added the subviews to UIView instances and then finally into the super view (declared within the viewDidLoad()):
self.logoImageView.insertSubview(logoImage, atIndex:1)
self.view.insertSubview(logoImageView, atIndex: 1)
Then finally applied the same func's now using the block based animations as suggested by rdelmar and recommended by Apple since iOS 4.0 (outside of, and after, the viewDidLoad()):
// Keyboard Auto Scroll
func textFieldDidBeginEditing(textField: UITextField!) {
self.animateTextField(textField, up: true)
}
func textFieldDidEndEditing(textField: UITextField!) {
self.animateTextField(textField, up: false)
}
func animateTextField(textField:UITextField,up: Bool){
let resultMovementDistance:Int = -xx
let movementDistance:Int = -xx
let movementDuration:NSTimeInterval = 0.xx
var resultMovement = CGFloat(Int((up ? resultMovementDistance : -resultMovementDistance)))
var otherMovement = CGFloat(Int((up ? movementDistance : -movementDistance)))
var logoMovement = otherMovement/5
UIView.animateWithDuration(
movementDuration,
delay: 0,
options: UIViewAnimationOptions.CurveEaseIn, animations:{
self.otherView.frame = CGRectOffset(self.otherView.frame,0,otherMovement)},
completion:nil)
UIView.animateWithDuration(
movementDuration,
delay: 0,
options: UIViewAnimationOptions.CurveEaseIn, animations:{
self.logoImageView.frame = CGRectOffset(self.logoImageView.frame,0,logoMovement)},
completion:nil)
UIView.animateWithDuration(
movementDuration,
delay: 0,
options: UIViewAnimationOptions.CurveEaseIn, animations:{
self.resultView.frame = CGRectOffset(self.resultView.frame,0,resultMovement)},
completion:nil)
}
Note: I did struggle with nesting the animations in the block, but I'm glad that it worked out. I hope this helps.

Resources