How to make an animation shadowOffset in Swift? - swift

I wrote the code but I can not understand why it does not work...
func animate(vc: UIView) {
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
vc.layer.add(animationX, forKey: animationX.keyPath)
}
#IBAction func buttonTapped(_ sender: UIButton) {
animate(vc: sender)
}
Does anyone know how this works?

Couple of things missing
shadowPath
shadowOpacity
vc.layer.masksToBounds = false
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
vc.layer.shadowOpacity = 1.0
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
vc.layer.add(animationX, forKey: animationX.keyPath)
By default shadowOpacity is 0.
Final O/P
EDIT:
If you want shadow to persist in its position even after animation specify
fillMode
isRemovedOnCompletion
final code will look like
func animate(vc: UIView) {
vc.layer.masksToBounds = false
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
vc.layer.shadowOpacity = 1.0
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
animationX.fillMode = .forwards
animationX.isRemovedOnCompletion = false
vc.layer.add(animationX, forKey: animationX.keyPath)
}
Final O/P looks like:

Related

Getting trouble when hovering a custom segmented control in swift

I tried to create custom segmented control which should change its look if you are hovering it. But it does not work as I expected.
Here's the code (I am sorry that it is that long but I already made it 200 lines shorter then it was):
class MySegmentedControl: UIView {
var state = MySegmentedControl_State.unknown
var buttons = [MySegmentedControl_ButtonView]()
func setUpView(){
let view = UIView(frame: self.frame)
view.frame.origin.x = 0
view.frame.origin.y = 0
view.addSubview(holderView())
self.addSubview(view)
}
func holderView() -> UIView{
let view = UIView(frame: CGRect(origin: CGPoint(x: 100, y: 0), size: CGSize(width: 490, height: 70)))
view.layer.borderWidth = 5
view.layer.borderColor = UIColor.gray.cgColor
view.layer.cornerRadius = view.frame.height / 2
view.layer.masksToBounds = true
view.clipsToBounds = true
view.backgroundColor = #colorLiteral(red: 0.5741485357, green: 0.5741624236, blue: 0.574154973, alpha: 1)
//place the first button
let button_1 = MySegmentedControl_ButtonView(text: "One", frame: CGRect(x: 0, y: 0, width: 163.3333, height: 70), type: .one, delegate: self)
//place the second Button
let button_2 = MySegmentedControl_ButtonView(text: "Two", frame: CGRect(x: 163.3333, y: 0, width: 163.3333, height: 70), type: .two, delegate: self)
//place the third Button
let button_3 = MySegmentedControl_ButtonView(text: "Three", frame: CGRect(x: 163.3333*2, y: 0, width: 163.3333, height: 70), type: .three, delegate: self)
buttons.append(button_1); buttons.append(button_2); buttons.append(button_3)
view.addSubview(button_1)
view.addSubview(button_2)
view.addSubview(button_3)
return view
}
class MySegmentedControl_ButtonView: UIView{
private var selected = false
private var hovering = false
var text = ""
private var type: MySegmentedControl_State
private var delegate: MySegmentedControl_ButtonView_Delegate
private var label = UILabel()
func setUpView(){
layer.cornerRadius = frame.height/2
let label = UILabel(frame: frame)
self.label = label
label.tintColor = .white
label.text = text
label.sizeToFit()
label.center = self.center
label.font = label.font.withSize(15)
let regionizer = UIHoverGestureRecognizer(target: self, action: #selector(didHover(_:)))
addGestureRecognizer(regionizer)
addSubview(label)
//set up the button
let button = UIButton(frame: bounds, primaryAction: UIAction(handler: { [self] action in
selected = true
delegate.shouldChangeState(to: type)
delegate.shouldDeselectOthers(without: text)
if !hovering{
backgroundColor = #colorLiteral(red: 0.9961533629, green: 0.9931518435, blue: 1, alpha: 0.8)
}else{
self.backgroundColor = #colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 0.9435433103)
}
}))
addSubview(button)
}
func deselect(){
self.selected = false
if hovering{
backgroundColor = #colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 0.15)
UIView.animate(withDuration: 0.2) {[self]in
label.frame.origin.y = 10
label.font = label.font.withSize(12)
}
}else{
backgroundColor = #colorLiteral(red: 0.2605174184, green: 0.2605243921, blue: 0.260515637, alpha: 0.15)
UIView.animate(withDuration: 0.2) {[self]in
label.frame.origin.y = 10
label.font = label.font.withSize(12)
}
}
}
#objc
func didHover(_ recognizer: UIHoverGestureRecognizer){
switch recognizer.state{
case .began, .changed:
hovering = true
if selected{
backgroundColor = #colorLiteral(red: 0.7540688515, green: 0.7540867925, blue: 0.7540771365, alpha: 0.15)
UIView.animate(withDuration: 0.2) {[self]in
label.frame.origin.y = 10
label.font = label.font.withSize(12)
}
}else{
backgroundColor = #colorLiteral(red: 0.2605174184, green: 0.2605243921, blue: 0.260515637, alpha: 0.15)
UIView.animate(withDuration: 0.2) {[self]in
label.frame.origin.y = 10
label.font = label.font.withSize(12)
}
}
case .ended:
hovering = false
if selected{
self.backgroundColor = #colorLiteral(red: 0.9961533629, green: 0.9931518435, blue: 1, alpha: 0.2)
UIView.animate(withDuration: 0.2) {[self]in
label.center.y = center.y
label.font = label.font.withSize(15)
}
}else{
self.backgroundColor = .clear
UIView.animate(withDuration: 0.2) {[self]in
label.center.y = center.y
label.font = label.font.withSize(15)
}
}
default:break
}
}
init(text: String, frame: CGRect, type: MySegmentedControl_State, delegate: MySegmentedControl_ButtonView_Delegate){
self.type = type
self.delegate = delegate
super.init(frame: frame)
self.text = text
setUpView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
extension MySegmentedControl: MySegmentedControl_ButtonView_Delegate{
func shouldDeselectOthers(without: String) {
for button in buttons{
if button.text != without{
button.deselect()
}
}
}
func shouldChangeState(to state: MySegmentedControl_State) {
self.state = state
}
}
protocol MySegmentedControl_ButtonView_Delegate{
func shouldDeselectOthers(without: String)
func shouldChangeState(to state: MySegmentedControl_State)
}
enum MySegmentedControl_State: String{
case unknown = "Non specific case avalaible"
case one = "One selected"
case two = "Two selected"
case three = "Three selected"
}
But the second of my buttons is displayed as the third and the the third does not get displayed, but if I hover the place where button two SHOULD be, it still gets hovered.
Here is a shout video:
Video showing problems with this code
My App is running on MacOS with MacCatalyst
In setUpView() inside class MySegmentedControl_ButtonView, you are trying to set the label's position with:
label.center = self.center
However, self.center is relative to self's superview. So your labels are being shifted.
If you change that line to:
label.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
the label centering will be correct.
As I asked in my comment though... why aren't you using auto-layout? It would make things much easier (and much more flexible).

How can I extract the uislider gradient color at the thumb position?

func gradientImage(size: CGSize, colorSet: [CGColor]) throws -> UIImage? {
let tgl = CAGradientLayer()
tgl.frame = CGRect.init(x:0, y:0, width:size.width, height: size.height)
tgl.cornerRadius = tgl.frame.height / 2
tgl.masksToBounds = false
tgl.colors = colorSet
tgl.startPoint = CGPoint.init(x:0.0, y:0.5)
tgl.endPoint = CGPoint.init(x:1.0, y:0.5)
UIGraphicsBeginImageContextWithOptions(size, tgl.isOpaque, 0.0);
guard let context = UIGraphicsGetCurrentContext() else { return nil }
tgl.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()?.resizableImage(withCapInsets:
UIEdgeInsets.init(top: 0, left: size.height, bottom: 0, right: size.height))
UIGraphicsEndImageContext()
return image
}
func setSliderGradient() {
let minTrackStartColor = UIColor(red:111/255, green: 111/255, blue: 111/255, alpha: 1.0)
let maxTrackColor = UIColor(red: 222/255, green: 222/255, blue: 222/255, alpha: 1.0)
do {
bottomNavBar.slider.setMinimumTrackImage(try bottomNavBar.gradientImage(
size: CGSize(width: bottomNavBar.slider.frame.width, height: 2),
colorSet: [minTrackStartColor.cgColor, maxTrackColor.cgColor]),
for: .normal)
bottomNavBar.slider.setMaximumTrackImage(try bottomNavBar.gradientImage(
size: CGSize(width: bottomNavBar.slider.frame.width, height: 2),
colorSet: [minTrackStartColor.cgColor, maxTrackColor.cgColor]),
for: .normal)
let thumb = UIView(frame: CGRect(x: 0, y: 0, width: 19, height: 10))
thumb.backgroundColor = UIColor(red: 222/255, green: 222/255, blue: 222/255, alpha: 1)
thumb.layer.cornerRadius = 5
bottomNavBar.slider.setThumbImage(thumb.asImage(), for: .normal)
} catch {
bottomNavBar.slider.minimumTrackTintColor = minTrackStartColor
bottomNavBar.slider.maximumTrackTintColor = maxTrackColor
}
}
In uislider, greadient is set as above code.
I want to color the thumb of the location according to the movement of the thumb.
How can I extract the uislider gradient color at the thumb position?
Try to create a gradient layer and update startPoint, endPoint and location depending on your current slider value.
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorStart.cgColor, colorEnd.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [0, 1]
gradientLayer.frame = bounds

How to change the color of the Mask View?

I am not sure if I understand the concept of Masking correctly but I am trying to recreate the Twitter logo expansion animation in their app:
Twitter Logo expansion
I have this code so far:
class LaunchScreenViewController: UIViewController {
var mask: CALayer!
override func viewDidLoad() {
setUpViewMask()
}
func setUpViewMask() {
mask = CALayer()
mask.contents = UIImage(named: "logo_mask")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask!.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask!.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
view.layer.mask = mask
}
}
The output of this is:
How would I change the black background to be blue? I tried doing but it didn't seem to work:
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
Create an intermediate layer where you apply mask. Set the background of your view to the desired background, and set background color of the intermediate layer to the color that you wish your mask to appear in. Something like this,
view.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1) // set background of the view portion that do not include mask
let parentLayer = CALayer()
parentLayer.frame = view.bounds
parentLayer.backgroundColor = UIColor.white.cgColor // sets background of mask
view.layer.addSublayer(parentLayer)
let mask = CALayer()
mask.contents = UIImage(named: "twitter.png")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
parentLayer.mask = mask
This can be achieved by changing the background color of appDelegate's window...
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.backgroundColor = UIColor.blue

Swift 2.1 - How do I change the uidatepicker so it only allows for time instead of date?

The following code below allows for the user to select a date, however I want to change that to 'Time' via AM/PM, so the user can only select a set time instead it being a date. I want this separate and not combined, I appreciate if someone could help me here thanks.
import Foundation
import UIKit
import QuartzCore
class DatePickerDialog: UIView {
typealias DatePickerCallback = (date: NSDate) -> Void
/* Consts */
private let kDatePickerDialogDefaultButtonHeight: CGFloat = 50
private let kDatePickerDialogDefaultButtonSpacerHeight: CGFloat = 1
private let kDatePickerDialogCornerRadius: CGFloat = 7
private let kDatePickerDialogDoneButtonTag: Int = 1
/* Views */
private var dialogView: UIView!
private var titleLabel: UILabel!
private var datePicker: UIDatePicker!
private var cancelButton: UIButton!
private var doneButton: UIButton!
/* Vars */
private var defaultDate: NSDate?
private var datePickerMode: UIDatePickerMode?
private var callback: DatePickerCallback?
/* Overrides */
init() {
super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
setupView()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func setupView() {
self.dialogView = createContainerView()
self.dialogView!.layer.shouldRasterize = true
self.dialogView!.layer.rasterizationScale = UIScreen.mainScreen().scale
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.mainScreen().scale
self.dialogView!.layer.opacity = 0.5
self.dialogView!.layer.transform = CATransform3DMakeScale(1.3, 1.3, 1)
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
self.addSubview(self.dialogView!)
UIApplication.sharedApplication().windows.first!.addSubview(self)
}
/* Handle device orientation changes */
func deviceOrientationDidChange(notification: NSNotification) {
/* TODO */
}
/* Create the dialog view, and animate opening the dialog */
func show(title: String, datePickerMode: UIDatePickerMode = .Date, callback: DatePickerCallback) {
show(title, doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: datePickerMode, callback: callback)
}
func show(title: String, doneButtonTitle: String, cancelButtonTitle: String, defaultDate: NSDate = NSDate(), datePickerMode: UIDatePickerMode = .Date, callback: DatePickerCallback) {
self.titleLabel.text = title
self.doneButton.setTitle(doneButtonTitle, forState: .Normal)
self.cancelButton.setTitle(cancelButtonTitle, forState: .Normal)
self.datePickerMode = datePickerMode
self.callback = callback
self.defaultDate = defaultDate
self.datePicker.datePickerMode = self.datePickerMode ?? .Date
self.datePicker.date = self.defaultDate ?? NSDate()
/* Anim */
UIView.animateWithDuration(
0.2,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: { () -> Void in
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
self.dialogView!.layer.opacity = 1
self.dialogView!.layer.transform = CATransform3DMakeScale(1, 1, 1)
},
completion: nil
)
}
/* Dialog close animation then cleaning and removing the view from the parent */
private func close() {
let currentTransform = self.dialogView.layer.transform
let startRotation = (self.valueForKeyPath("layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0
let rotation = CATransform3DMakeRotation((CGFloat)(-startRotation + M_PI * 270 / 180), 0, 0, 0)
self.dialogView.layer.transform = CATransform3DConcat(rotation, CATransform3DMakeScale(1, 1, 1))
self.dialogView.layer.opacity = 1
UIView.animateWithDuration(
0.2,
delay: 0,
options: UIViewAnimationOptions.TransitionNone,
animations: { () -> Void in
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
self.dialogView.layer.transform = CATransform3DConcat(currentTransform, CATransform3DMakeScale(0.6, 0.6, 1))
self.dialogView.layer.opacity = 0
}) { (finished: Bool) -> Void in
for v in self.subviews {
v.removeFromSuperview()
}
self.removeFromSuperview()
}
}
/* Creates the container view here: create the dialog, then add the custom content and buttons */
private func createContainerView() -> UIView {
let screenSize = countScreenSize()
let dialogSize = CGSizeMake(
300,
230
+ kDatePickerDialogDefaultButtonHeight
+ kDatePickerDialogDefaultButtonSpacerHeight)
// For the black background
self.frame = CGRectMake(0, 0, screenSize.width, screenSize.height)
// This is the dialog's container; we attach the custom content and the buttons to this one
let dialogContainer = UIView(frame: CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height))
// First, we style the dialog to match the iOS8 UIAlertView >>>
let gradient: CAGradientLayer = CAGradientLayer(layer: self.layer)
gradient.frame = dialogContainer.bounds
gradient.colors = [UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor,
UIColor(red: 233/255, green: 233/255, blue: 233/255, alpha: 1).CGColor,
UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor]
let cornerRadius = kDatePickerDialogCornerRadius
gradient.cornerRadius = cornerRadius
dialogContainer.layer.insertSublayer(gradient, atIndex: 0)
dialogContainer.layer.cornerRadius = cornerRadius
dialogContainer.layer.borderColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1).CGColor
dialogContainer.layer.borderWidth = 1
dialogContainer.layer.shadowRadius = cornerRadius + 5
dialogContainer.layer.shadowOpacity = 0.1
dialogContainer.layer.shadowOffset = CGSizeMake(0 - (cornerRadius + 5) / 2, 0 - (cornerRadius + 5) / 2)
dialogContainer.layer.shadowColor = UIColor.blackColor().CGColor
dialogContainer.layer.shadowPath = UIBezierPath(roundedRect: dialogContainer.bounds, cornerRadius: dialogContainer.layer.cornerRadius).CGPath
// There is a line above the button
let lineView = UIView(frame: CGRectMake(0, dialogContainer.bounds.size.height - kDatePickerDialogDefaultButtonHeight - kDatePickerDialogDefaultButtonSpacerHeight, dialogContainer.bounds.size.width, kDatePickerDialogDefaultButtonSpacerHeight))
lineView.backgroundColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1)
dialogContainer.addSubview(lineView)
// ˆˆˆ
//Title
self.titleLabel = UILabel(frame: CGRectMake(10, 10, 280, 30))
self.titleLabel.textAlignment = NSTextAlignment.Center
self.titleLabel.font = UIFont.boldSystemFontOfSize(17)
dialogContainer.addSubview(self.titleLabel)
self.datePicker = UIDatePicker(frame: CGRectMake(0, 30, 0, 0))
self.datePicker.autoresizingMask = UIViewAutoresizing.FlexibleRightMargin
self.datePicker.frame.size.width = 300
dialogContainer.addSubview(self.datePicker)
// Add the buttons
addButtonsToView(dialogContainer)
return dialogContainer
}
/* Add buttons to container */
private func addButtonsToView(container: UIView) {
let buttonWidth = container.bounds.size.width / 2
self.cancelButton = UIButton(type: UIButtonType.Custom) as UIButton
self.cancelButton.frame = CGRectMake(
0,
container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
buttonWidth,
kDatePickerDialogDefaultButtonHeight
)
self.cancelButton.setTitleColor(UIColor(red: 0, green: 0.5, blue: 1, alpha: 1), forState: UIControlState.Normal)
self.cancelButton.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5), forState: UIControlState.Highlighted)
self.cancelButton.titleLabel!.font = UIFont.boldSystemFontOfSize(14)
self.cancelButton.layer.cornerRadius = kDatePickerDialogCornerRadius
container.addSubview(self.cancelButton)
self.doneButton = UIButton(type: UIButtonType.Custom) as UIButton
self.doneButton.frame = CGRectMake(
buttonWidth,
container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
buttonWidth,
kDatePickerDialogDefaultButtonHeight
)
self.doneButton.tag = kDatePickerDialogDoneButtonTag
self.doneButton.setTitleColor(UIColor(red: 0, green: 0.5, blue: 1, alpha: 1), forState: UIControlState.Normal)
self.doneButton.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5), forState: UIControlState.Highlighted)
self.doneButton.titleLabel!.font = UIFont.boldSystemFontOfSize(14)
self.doneButton.layer.cornerRadius = kDatePickerDialogCornerRadius
self.doneButton.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
container.addSubview(self.doneButton)
}
func buttonTapped(sender: UIButton!) {
if sender.tag == kDatePickerDialogDoneButtonTag {
self.callback?(date: self.datePicker.date)
}
close()
}
/* Helper function: count and return the screen's size */
func countScreenSize() -> CGSize {
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
return CGSizeMake(screenWidth, screenHeight)
}
}
Here is the action in a separate view controller.
#IBAction func datePickerTapped(sender: AnyObject) {
DatePickerDialog().show("Select Date of Incident", doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: .Date) {
(date) -> Void in
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy" //format style. you can change according to yours
let dateString = dateFormatter.stringFromDate(date)
self.textField3.text = dateString
}
}
If by "separately," you mean prompting for the date and then prompting for the time, you can simply call the show method again and pass in the appropriate UIDatePickerMode (.Time in this case) and format your time according to your requirements.
Like so:
DatePickerDialog().show("Select Time of Incident", doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: .Time) {
//format your time accordingly
//self.textField3.text = timeString
}

How to remove the time from Date Picker?

What I want to achieve here is to remove the "TIME" from the UITextfield once I have selected a date. For example "D/M/Y" I want this only to display and not the time "00:00:00" or "+0000".
This piece of code does not require the element of "UIDate Picker" to be selected as I already know how to disable the time this way through the attributes inspector but not this way.
I think it needs to be done programmatically.
Code in the separate class:
import Foundation
import UIKit
import QuartzCore
class DatePickerDialog: UIView {
typealias DatePickerCallback = (date: NSDate) -> Void
/* Consts */
private let kDatePickerDialogDefaultButtonHeight: CGFloat = 50
private let kDatePickerDialogDefaultButtonSpacerHeight: CGFloat = 1
private let kDatePickerDialogCornerRadius: CGFloat = 7
private let kDatePickerDialogDoneButtonTag: Int = 1
/* Views */
private var dialogView: UIView!
private var titleLabel: UILabel!
private var datePicker: UIDatePicker!
private var cancelButton: UIButton!
private var doneButton: UIButton!
/* Vars */
private var defaultDate: NSDate?
private var datePickerMode: UIDatePickerMode?
private var callback: DatePickerCallback?
/* Overrides */
init() {
super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
setupView()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func setupView() {
self.dialogView = createContainerView()
self.dialogView!.layer.shouldRasterize = true
self.dialogView!.layer.rasterizationScale = UIScreen.mainScreen().scale
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.mainScreen().scale
self.dialogView!.layer.opacity = 0.5
self.dialogView!.layer.transform = CATransform3DMakeScale(1.3, 1.3, 1)
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
self.addSubview(self.dialogView!)
UIApplication.sharedApplication().windows.first!.addSubview(self)
}
/* Handle device orientation changes */
func deviceOrientationDidChange(notification: NSNotification) {
/* TODO */
}
/* Create the dialog view, and animate opening the dialog */
func show(title: String, datePickerMode: UIDatePickerMode = .Date, callback: DatePickerCallback) {
show(title, doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: datePickerMode, callback: callback)
}
func show(title: String, doneButtonTitle: String, cancelButtonTitle: String, defaultDate: NSDate = NSDate(), datePickerMode: UIDatePickerMode = .Date, callback: DatePickerCallback) {
self.titleLabel.text = title
self.doneButton.setTitle(doneButtonTitle, forState: .Normal)
self.cancelButton.setTitle(cancelButtonTitle, forState: .Normal)
self.datePickerMode = datePickerMode
self.callback = callback
self.defaultDate = defaultDate
self.datePicker.datePickerMode = self.datePickerMode ?? .Date
self.datePicker.date = self.defaultDate ?? NSDate()
/* Anim */
UIView.animateWithDuration(
0.2,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: { () -> Void in
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
self.dialogView!.layer.opacity = 1
self.dialogView!.layer.transform = CATransform3DMakeScale(1, 1, 1)
},
completion: nil
)
}
/* Dialog close animation then cleaning and removing the view from the parent */
private func close() {
let currentTransform = self.dialogView.layer.transform
let startRotation = (self.valueForKeyPath("layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0
let rotation = CATransform3DMakeRotation((CGFloat)(-startRotation + M_PI * 270 / 180), 0, 0, 0)
self.dialogView.layer.transform = CATransform3DConcat(rotation, CATransform3DMakeScale(1, 1, 1))
self.dialogView.layer.opacity = 1
UIView.animateWithDuration(
0.2,
delay: 0,
options: UIViewAnimationOptions.TransitionNone,
animations: { () -> Void in
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
self.dialogView.layer.transform = CATransform3DConcat(currentTransform, CATransform3DMakeScale(0.6, 0.6, 1))
self.dialogView.layer.opacity = 0
}) { (finished: Bool) -> Void in
for v in self.subviews {
v.removeFromSuperview()
}
self.removeFromSuperview()
}
}
/* Creates the container view here: create the dialog, then add the custom content and buttons */
private func createContainerView() -> UIView {
let screenSize = countScreenSize()
let dialogSize = CGSizeMake(
300,
230
+ kDatePickerDialogDefaultButtonHeight
+ kDatePickerDialogDefaultButtonSpacerHeight)
// For the black background
self.frame = CGRectMake(0, 0, screenSize.width, screenSize.height)
// This is the dialog's container; we attach the custom content and the buttons to this one
let dialogContainer = UIView(frame: CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height))
// First, we style the dialog to match the iOS8 UIAlertView >>>
let gradient: CAGradientLayer = CAGradientLayer(layer: self.layer)
gradient.frame = dialogContainer.bounds
gradient.colors = [UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor,
UIColor(red: 233/255, green: 233/255, blue: 233/255, alpha: 1).CGColor,
UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor]
let cornerRadius = kDatePickerDialogCornerRadius
gradient.cornerRadius = cornerRadius
dialogContainer.layer.insertSublayer(gradient, atIndex: 0)
dialogContainer.layer.cornerRadius = cornerRadius
dialogContainer.layer.borderColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1).CGColor
dialogContainer.layer.borderWidth = 1
dialogContainer.layer.shadowRadius = cornerRadius + 5
dialogContainer.layer.shadowOpacity = 0.1
dialogContainer.layer.shadowOffset = CGSizeMake(0 - (cornerRadius + 5) / 2, 0 - (cornerRadius + 5) / 2)
dialogContainer.layer.shadowColor = UIColor.blackColor().CGColor
dialogContainer.layer.shadowPath = UIBezierPath(roundedRect: dialogContainer.bounds, cornerRadius: dialogContainer.layer.cornerRadius).CGPath
// There is a line above the button
let lineView = UIView(frame: CGRectMake(0, dialogContainer.bounds.size.height - kDatePickerDialogDefaultButtonHeight - kDatePickerDialogDefaultButtonSpacerHeight, dialogContainer.bounds.size.width, kDatePickerDialogDefaultButtonSpacerHeight))
lineView.backgroundColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1)
dialogContainer.addSubview(lineView)
// ˆˆˆ
//Title
self.titleLabel = UILabel(frame: CGRectMake(10, 10, 280, 30))
self.titleLabel.textAlignment = NSTextAlignment.Center
self.titleLabel.font = UIFont.boldSystemFontOfSize(17)
dialogContainer.addSubview(self.titleLabel)
self.datePicker = UIDatePicker(frame: CGRectMake(0, 30, 0, 0))
self.datePicker.autoresizingMask = UIViewAutoresizing.FlexibleRightMargin
self.datePicker.frame.size.width = 300
dialogContainer.addSubview(self.datePicker)
// Add the buttons
addButtonsToView(dialogContainer)
return dialogContainer
}
/* Add buttons to container */
private func addButtonsToView(container: UIView) {
let buttonWidth = container.bounds.size.width / 2
self.cancelButton = UIButton(type: UIButtonType.Custom) as UIButton
self.cancelButton.frame = CGRectMake(
0,
container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
buttonWidth,
kDatePickerDialogDefaultButtonHeight
)
self.cancelButton.setTitleColor(UIColor(red: 0, green: 0.5, blue: 1, alpha: 1), forState: UIControlState.Normal)
self.cancelButton.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5), forState: UIControlState.Highlighted)
self.cancelButton.titleLabel!.font = UIFont.boldSystemFontOfSize(14)
self.cancelButton.layer.cornerRadius = kDatePickerDialogCornerRadius
container.addSubview(self.cancelButton)
self.doneButton = UIButton(type: UIButtonType.Custom) as UIButton
self.doneButton.frame = CGRectMake(
buttonWidth,
container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
buttonWidth,
kDatePickerDialogDefaultButtonHeight
)
self.doneButton.tag = kDatePickerDialogDoneButtonTag
self.doneButton.setTitleColor(UIColor(red: 0, green: 0.5, blue: 1, alpha: 1), forState: UIControlState.Normal)
self.doneButton.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5), forState: UIControlState.Highlighted)
self.doneButton.titleLabel!.font = UIFont.boldSystemFontOfSize(14)
self.doneButton.layer.cornerRadius = kDatePickerDialogCornerRadius
self.doneButton.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
container.addSubview(self.doneButton)
}
func buttonTapped(sender: UIButton!) {
if sender.tag == kDatePickerDialogDoneButtonTag {
self.callback?(date: self.datePicker.date)
}
close()
}
/* Helper function: count and return the screen's size */
func countScreenSize() -> CGSize {
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
return CGSizeMake(screenWidth, screenHeight)
}
}
Code here defined in Viewcontroller.swift:
#IBAction func datePickerTapped(sender: AnyObject) {
DatePickerDialog().show("Select Date of Incident", doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: .Date) {
(date) -> Void in
self.textField3.text = "\(date)"
}
}
Its simple
change this line to
self.textField3.text = "\(date)"
to
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd" //format style. you can change according to yours
var dateString = dateFormatter.stringFromDate(date)
self.textField3.text = dateString