UIAccessibilityTraitAdjustable methods for UISlider not responding - ios

I'm trying to figure out how to set the accessibility Increment/ Decrement of an UISlider with stepping. It keeps saying that the value is 0%, which it shouldn't. I also wonder if this is the reason why the accessibilityValue is not working..
ViewController
import UIKit
class RateAppViewController: UIViewController {
//MARK: IBOutlets
#IBOutlet weak var ratingSlider: UISlider!
let steps: Float = 0.2
override func viewDidLoad() {
super.viewDidLoad()
// UpdateUI
updateUI()
// InitalizeAccessibility
initalizeAccessibility()
}
private func updateUI() {
ratingSlider.value = 0.2
ratingSlider.minimumValue = 0.2
ratingSlider.maximumValue = 1.0
}
private func initalizeAccessibility() {
ratingSlider.isAccessibilityElement = true
ratingSlider.accessibilityTraits = UIAccessibilityTraitAdjustable
ratingSlider.accessibilityLabel = NSLocalizedString("Rating", comment: "RatingView Label")
ratingSlider.accessibilityIncrement()
ratingSlider.accessibilityDecrement()
}
override func accessibilityIncrement() {
ratingSlider.value += steps
setRating(ratingSlider.value)
}
override func accessibilityDecrement() {
ratingSlider.value -= steps
setRating(ratingSlider.value)
}
private func setRating(value: Float) {
let stars: Int = Int(value * 5)
print(stars)
if value == 0.2 {
ratingSlider.accessibilityValue = NSLocalizedString("1 star", comment: "One Star RatingSlider")
} else {
ratingSlider.accessibilityValue = NSLocalizedString("\(stars) Stars", comment: "Multiple Stars RatingSlider")
}
}
#IBAction func ratingValueChanged(sender: UISlider) {
let roundSteps = round(sender.value / steps) * steps
sender.value = roundSteps
}
}

I believe you need to subclass UISlider and implement the methods in that class.

Related

Swift Class has another class from Pod with UiViewController and get Nil on outlets because of that

First of all, sorry the english.
I have a project in Swift 4.2. One of the Pods is imported and added to a class "Principal View Controller". This Pod has de UIViewController and i cannot add it on the class because it's used on the Pod and Xcode doesn't alow multiple inheritance.
If I remove the Pod from the class the Iboutlets works without problem but the pod is not working ( it's used for side menu ). If i leave the Pod added, the Iboutlets just get nil value.
I track in a debug the code and pass on 2 of the ViewDidLoad and nothing load value on Outlets if Pod is added.
Maybe someone knows the way to fix this?
**I remove some code from classes because it's way more than the 300000 characters that stackoverflow allow...
//
// PrincipalViewController.swift
//
import UIKit
import SwiftyJSON
import JLSlideMenuController
import Alamofire
class PrincipalViewController: JLSlideNavigationController, UIImagePickerControllerDelegate, URLSessionDownloadDelegate, UIGestureRecognizerDelegate {
#IBOutlet weak var scrollViewWeather: UIScrollView!
#IBOutlet var profileImage:UIImageView!
#IBOutlet var parentView: UIView!
#IBOutlet var lblUserName:UILabel!
#IBOutlet var menuButton:UIButton!
var jsonVar:JSON!
var rutasDisponibles : [Ruta]!
var userDefaults = UserDefaults.standard
var viewDayArray = [UIView](repeating: UIView(), count: 7)
var labelDayArray = [UILabel](repeating: UILabel(), count: 7)
var labelTempDayArray = [UILabel](repeating: UILabel(), count: 7)
var ivDayArray = [UIImageView](repeating: UIImageView(), count: 7)
var taskDescargaKmls : URLSessionTask!
var contador = 1
#IBOutlet weak var btMisRutas: UIButton!
#IBOutlet weak var btRutas: UIButton!
#IBOutlet weak var btInfoMunicipio: UIButton!
var jlSlide: JLSlideNavigationController!
lazy var session : Foundation.URLSession = {
let config = URLSessionConfiguration.ephemeral
config.allowsCellularAccess = false
let session = Foundation.URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
return session
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
UIApplication.shared.isStatusBarHidden = false
profileImage.layer.borderColor = UIColor.lightGray.cgColor
let lang = UserDefaults.standard.string(forKey: "LANG");
btRutas.setTitle(Languages.translateText("rutas", language: lang!), for: UIControl.State())
btInfoMunicipio.setTitle(Languages.translateText("info_municipio", language: lang!), for: UIControl.State())
btMisRutas.setTitle(Languages.translateText("mis_rutas", language: lang!), for: UIControl.State())
if(!OnlineStatus.isConnectedToNetwork()){
scrollViewWeather.isHidden = true
}
}
#IBAction func sideMenu(_ sender: UIButton) {
if menuIsPresented(){
self.hideMenu(animated: true)
}
else{
self.showMenu(animated: true)
}
}
override func viewDidLoad() {
super.viewDidLoad()
let configuration = URLSessionConfiguration.background(withIdentifier: "com.website.background")
let gesture = UITapGestureRecognizer(target: self, action: #selector(PrincipalViewController.closeMenu(_:)))
gesture.numberOfTapsRequired = 1
gesture.numberOfTouchesRequired = 1
gesture.delegate = self
self.parentView.addGestureRecognizer(gesture)
addSlideMenu("MenuViewController",storyboardName: "Main",distToTop: 0, widthAspectRatio: 0.8, distToBottom: 0,comeFromLeft: true)
}
The pod is JSlideMenuController : https://cocoapods.org/pods/JLSlideMenuController
//
// JLSlideMenuViewController.swift
// Pods
//
// Created by José Lucas Souza das Chagas on 20/03/16.
//
//
import UIKit
public class JLSlideMenuViewController: UIViewController {
public var attachedNavController:JLSlideNavigationController!
//constraints
var sideDist:NSLayoutConstraint!
var distToTopC:NSLayoutConstraint!
var distToBottomC:NSLayoutConstraint!
var widthC:NSLayoutConstraint!
//
/**
TRUE to enable the menu FALSE to disable
The value of this enable or disable the animations and gestures to show and hide the menu
*/
public var enabled:Bool = true{
didSet{
if enabled == false{
attachedNavController.hideMenu(animated: false)
}
}
}
override public func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.view.layoutIfNeeded()
}
override public func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
//print(parent!.childViewControllers)
}
//public override func canBecomeFirstResponder() -> Bool {
public func canBecomeFirstResponder() -> Bool {
return true
}
override public func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//override public func prefersStatusBarHidden() -> Bool {
public func prefersStatusBarHidden() -> Bool {
return true
}
func removeConstraints(){
self.view.window!.removeConstraint(sideDist)
self.view.window!.removeConstraint(distToTopC)
self.view.window!.removeConstraint(distToBottomC)
self.view.removeConstraint(widthC)
}
/**
Call this method to present modally the correct view controller accordingly to some interaction
with the menu view controller
- parameter VCId: The Id of the view controller to show
- parameter storyboardName: the name of the storyboard where the view controller is
- parameter animated: true to transition with some animation or not
*/
public func presentControllerModally(VCId:String,storyboardName:String,animated:Bool){
let destinyVC = JLSlideNavigationController.loadMenuVC(identifier: VCId, storyboardName: storyboardName)
destinyVC.view.frame = self.attachedNavController.view.frame
self.attachedNavController.hideMenu(animated: false)
let menuSegue = UIStoryboardSegue(identifier: "actualViewToAnother", source: self.attachedNavController,
destination: destinyVC, performHandler: { () -> Void in
DispatchQueue.global(qos: .background).async {
// Background Thread
DispatchQueue.main.async {
// Run UI Updates
self.attachedNavController.topViewController!.present(destinyVC, animated: animated, completion: nil)
}
}
/*
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.attachedNavController.topViewController!.presentViewController(destinyVC, animated: animated, completion: nil)
})
*/
})
//self.prepareForSegue(menuSegue, sender: nil)
self.attachedNavController.topViewController!.prepare(for: menuSegue, sender: nil)
menuSegue.perform()
}
/**
Call this method to show the correct view controller accordingly to some interaction
with the menu view controller
Use this one if the view controller where the menu is right now have some navigation controller
- parameter VCId: The Id of the view controller to show
- parameter storyboardName: the name of the storyboard where the view controller is
- parameter animated: true to transition with some animation or not
*/
public func showController(VCId:String,storyboardName:String,animated:Bool){
let destinyVC = JLSlideNavigationController.loadMenuVC(identifier: VCId, storyboardName: storyboardName)
destinyVC.view.frame = self.attachedNavController.view.frame
self.attachedNavController.hideMenu(animated: false)
let menuSegue = UIStoryboardSegue(identifier: "actualViewToAnother", source: self.attachedNavController,
destination: destinyVC, performHandler: { () -> Void in
self.attachedNavController.pushViewController(destinyVC, animated: animated)
})
//self.prepareForSegue(menuSegue, sender: nil)
self.attachedNavController.prepare(for: menuSegue, sender: nil)
menuSegue.perform()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
//
// JLSlideNavigationController.swift
// Pods
//
// Created by José Lucas Souza das Chagas on 24/04/16.
//
//
import UIKit
open class JLSlideNavigationController: UINavigationController,UINavigationControllerDelegate {
/**
menuVCStoryboardID: The Id of your menu View Controller.
*/
#IBInspectable private(set) var menuVCStoryboardID:String?
/**
the name of the storyboard where your menu View Controller is.
*/
#IBInspectable private(set) var storyboardName:String?
/**
the value of the constraint that indicates the distance between your menu top and this VC top.
*/
#IBInspectable private(set) var distToTop:CGFloat = 0
/**
the value of the constraint that determine your menu Width.
*/
#IBInspectable private(set) var width:CGFloat = 250
/**
the value of the constraint that indicates the distance between your menu bottom and this VC bottom.
*/
#IBInspectable private(set) var distToBottom:CGFloat = 0
/**
the bolean value that indicates if your menu will come from left or from right of the window.
*/
#IBInspectable private(set) var comeFromLeft:Bool = true
/**
A bolean value that indicates to use or not shadow effects
*/
#IBInspectable private(set) var useShadowEffects:Bool = false
private var menuContainerView: UIView?
/**
The instace of your menu View Controller associated to this View Controller
*/
private(set) static var myMenuVC:JLSlideMenuViewController?
public static var panGes:UIPanGestureRecognizer?
public static var screeEdgePanGes:UIScreenEdgePanGestureRecognizer?
/**
Incicates that the pan gesture that were started enabled or not
*/
private var panEnabled:Bool = false
private var lastPanTouch:CGPoint?
override open func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
if let pan = JLSlideNavigationController.panGes{
pan.isEnabled = true
}
if let pan = JLSlideNavigationController.screeEdgePanGes{
pan.isEnabled = true
}
// Do any additional setup after loading the view.
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let _ = self.view.window{
checkIfShouldAddOrUpdateMenu()
}
print(self.view.window!.gestureRecognizers!.count)
}
open override func viewDidDisappear(_ animated: Bool) {
super.viewDidAppear(animated)
if let pan = JLSlideNavigationController.panGes{
pan.isEnabled = false
}
if let pan = JLSlideNavigationController.screeEdgePanGes{
pan.isEnabled = false
}
}
class func loadMenuVC(identifier:String,storyboardName:String)->UIViewController{
let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
return storyboard.instantiateViewController(withIdentifier: identifier)
}
//MARK: - NavigationController delegate methods
public func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
if let menuView = menuContainerView , let window = self.view.window{
window.bringSubviewToFront(menuView)
}
let subViews = viewController.view.subviews
if let screenEdgeGes = JLSlideNavigationController.screeEdgePanGes{
for subView in subViews{
if let gestures = subView.gestureRecognizers{
for gesture in gestures{
gesture.require(toFail: screenEdgeGes)
}
}
}
}
}
//MARK: - Gestures methods
private func addGestures(){
//Pan
if let window = self.view.window , let pan = JLSlideNavigationController.panGes{
window.removeGestureRecognizer(pan)
}
JLSlideNavigationController.panGes = UIPanGestureRecognizer(target: self, action: #selector(JLSlideNavigationController.panAction(panGes:)))
self.view.window?.addGestureRecognizer(JLSlideNavigationController.panGes!)
//Screen Edge pan
if let window = self.view.window , let pan = JLSlideNavigationController.screeEdgePanGes{
window.removeGestureRecognizer(pan)
}
JLSlideNavigationController.screeEdgePanGes = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(JLSlideNavigationController.screenEdgePanAction(edgePan:)))
if comeFromLeft{
JLSlideNavigationController.screeEdgePanGes!.edges = UIRectEdge.left
}
else{
JLSlideNavigationController.screeEdgePanGes!.edges = UIRectEdge.right
}
self.view.window?.addGestureRecognizer(JLSlideNavigationController.screeEdgePanGes!)
JLSlideNavigationController.panGes!.require(toFail: JLSlideNavigationController.screeEdgePanGes!)
if let screenEdgeGes = JLSlideNavigationController.screeEdgePanGes, let topViewC = topViewController{
let subViews = topViewC.view.subviews
for subView in subViews{
if let gestures = subView.gestureRecognizers{
for gesture in gestures{
gesture.require(toFail: screenEdgeGes)
}
}
}
}
}
#objc public func screenEdgePanAction(edgePan:UIScreenEdgePanGestureRecognizer){
let currenLocation = edgePan.location(in: self.view)
if let menuView = menuContainerView, JLSlideNavigationController.myMenuVC!.enabled{
if edgePan.state == UIGestureRecognizer.State.began{
panEnabled = false
if !menuIsPresented(){
panEnabled = true
lastPanTouch = currenLocation
}
}
else if edgePan.state == UIGestureRecognizer.State.ended{//at the end of pan gesture check if the menu is near to show or hide completelly and then finishes the movement
panEnabled = false
let menuFrame = menuView.frame
if comeFromLeft{
if menuFrame.origin.x <= -menuFrame.size.width/2{
self.hideMenu(animated: true)
}
else if menuFrame.origin.x > -menuFrame.size.width/2{
self.showMenu(animated: true)
}
}
else{
if menuFrame.origin.x >= self.view.frame.width - menuFrame.size.width/2{
self.hideMenu(animated: true)
}
else if menuFrame.origin.x < self.view.frame.width - menuFrame.size.width/2{
self.showMenu(animated: true)
}
}
}
if panEnabled{//if the pan started at a right point continue
menuView.alpha = 1
let xDeslocamento = currenLocation.x - lastPanTouch!.x
lastPanTouch = currenLocation
if comeFromLeft{
if menuView.frame.origin.x + xDeslocamento >= -menuView.frame.width && menuView.frame.origin.x + xDeslocamento <= 0{
menuView.frame.origin = CGPoint(x:menuView.frame.origin.x + xDeslocamento ,y:menuView.frame.origin.y)
}
}
else{
if menuView.frame.origin.x + xDeslocamento >= self.view.frame.width - menuView.frame.width && menuView.frame.origin.x + xDeslocamento <= self.view.frame.width{
menuView.frame.origin = CGPoint(x:menuView.frame.origin.x + xDeslocamento ,y: menuView.frame.origin.y)
}
}
}
}
}
}

ios - Custom delegate method is not triggered

I have added a round button in TabBarController using the following code
import UIKit
protocol AddButtonProtocol: class {
func addButtonIsClicked()
}
class MainTabBar: UITabBar {
open var buttonDelegate: AddButtonProtocol?
private var middleButton = UIButton()
override open func awakeFromNib() {
super.awakeFromNib()
setupMiddleButton()
}
override open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.isHidden {
return super.hitTest(point, with: event)
}
let from = point
let to = middleButton.center
return sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)) <= 39 ? middleButton : super.hitTest(point, with: event)
}
func setupMiddleButton() {
middleButton.frame.size = CGSize(width: 70, height: 70)
middleButton.backgroundColor = .blue
middleButton.layer.cornerRadius = 35
middleButton.layer.masksToBounds = true
middleButton.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: 0)
middleButton.addTarget(self, action: #selector(test), for: .touchUpInside)
addSubview(middleButton)
}
#objc func test() {
print("add button is clicked")
buttonDelegate?.addButtonIsClicked()
}
}
It looks like this.
Now whenever I click that button, the method in HomeScreenVCViewController should be triggered. So I have implemented the protocol and delegates like this.
import UIKit
class HomeScreenVCViewController: UIViewController {
var addButtonDelegate: MainTabBar!
override func viewDidLoad() {
super.viewDidLoad()
addButtonDelegate?.buttonDelegate = self
}
}
extension HomeScreenVCViewController: AddButtonProtocol {
func addButtonIsClicked() {
print("protocol is working") // Not getting called
}
}
But its not working at all, addButtonIsClicked method is not getting triggered when I tap that round button. Any help will be appreciated.
Try this code:
override func viewDidLoad() {
super.viewDidLoad()
(tabBarController.tabBar as? MainTabBar)?.buttonDelegate = self
}
Delegate is not getting called b'coz addButtonDelegate is nil. You do not initialise addButtonDelegate so the addButtonDelegate object is nil
Solution
Either you need to make addButtonDelegate as an #IBOutlet or you need to initialise it in viewDidLoad: method.
Then only delegate will be called.
Example 1
#IBOutlet weak var addButtonDelegate: MainTabBar!
and in viewDidLoad
addButtonDelegate.buttonDelegate = self
Example 2
Create property like
var addButtonDelegate: MainTabBar?
in viewDidLoad initialise addButtonDelegate.
addButtonDelegate = MainTabBar() //or any other initialiser
addButtonDelegate?.buttonDelegate = self
You did not initialize MainTabBar in HomeScreenVCViewController. Thats why addButtonDelegate is nil
var addButtonDelegate: MainTabBar = MainTabBar()
override func viewDidLoad() {
super.viewDidLoad()
addButtonDelegate?.buttonDelegate = self
}

UIView disappears after user interaction

whenever I click a textfield inside the view, then click the other text field, the view disappears. Strange... Can anyone help?
I animate the view using facebook pop. Here is my animation engine code:
import UIKit
import pop
class AnimationEngine {
class var offScreenRightPosition: CGPoint {
return CGPoint(x: UIScreen.main.bounds.width + 250,y: UIScreen.main.bounds.midY - 75)
}
class var offScreenLeftPosition: CGPoint{
return CGPoint(x: -UIScreen.main.bounds.width,y: UIScreen.main.bounds.midY - 75)
}
class var offScreenTopPosition: CGPoint{
return CGPoint(x: UIScreen.main.bounds.midX,y: -UIScreen.main.bounds.midY)
}
class var screenCenterPosition: CGPoint {
return CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY - 75)
}
let ANIM_DELAY : Int = 1
var originalConstants = [CGFloat]()
var constraints: [NSLayoutConstraint]!
init(constraints: [NSLayoutConstraint]) {
for con in constraints {
originalConstants.append(con.constant)
con.constant = AnimationEngine.offScreenRightPosition.x
}
self.constraints = constraints
}
func animateOnScreen(_ delay: Int) {
let time = DispatchTime.now() + Double(Int64(Double(delay) * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
var index = 0
repeat {
let moveAnim = POPSpringAnimation(propertyNamed: kPOPLayoutConstraintConstant)
moveAnim?.toValue = self.originalConstants[index]
moveAnim?.springBounciness = 8
moveAnim?.springSpeed = 8
if (index < 0) {
moveAnim?.dynamicsFriction += 10 + CGFloat(index)
}
let con = self.constraints[index]
con.pop_add(moveAnim, forKey: "moveOnScreen")
index += 1
} while (index < self.constraints.count)
}
}
class func animateToPosisition(_ view: UIView, position: CGPoint, completion: ((POPAnimation?, Bool) -> Void)!) {
let moveAnim = POPSpringAnimation(propertyNamed: kPOPLayerPosition)
moveAnim?.toValue = NSValue(cgPoint: position)
moveAnim?.springBounciness = 8
moveAnim?.springSpeed = 8
moveAnim?.completionBlock = completion
view.pop_add(moveAnim, forKey: "moveToPosition")
}
}
Then here is my viewcontroller code where the view is inside in:
import UIKit
import pop
class LoginVC: UIViewController, UITextFieldDelegate {
override var prefersStatusBarHidden: Bool {
return true
}
#IBOutlet weak var emailLoginVCViewConstraint: NSLayoutConstraint!
#IBOutlet weak var emailLoginVCView: MaterialView!
#IBOutlet weak var emailAddressTextField: TextFieldExtension!
#IBOutlet weak var passwordTextField: TextFieldExtension!
var animEngine : AnimationEngine!
override func viewDidAppear(_ animated: Bool) {
self.emailLoginVCView.isUserInteractionEnabled = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.bringSubview(toFront: emailAddressTextField)
self.animEngine = AnimationEngine(constraints: [emailLoginVCViewConstraint])
self.emailAddressTextField.delegate = self
self.passwordTextField.delegate = self
emailAddressTextField.allowsEditingTextAttributes = false
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if (textField === emailAddressTextField) {
passwordTextField.becomeFirstResponder()
} else if (textField === passwordTextField) {
passwordTextField.resignFirstResponder()
} else {
// etc
}
return true
}
#IBAction func emailTapped(_ sender: AnyObject) {
AnimationEngine.animateToPosisition(emailLoginVCView, position: AnimationEngine.screenCenterPosition, completion: { (POPAnimation, Bool)
in
})
}
#IBAction func exitTapped(_ sender: AnyObject) {
AnimationEngine.animateToPosisition(emailLoginVCView, position: AnimationEngine.offScreenRightPosition, completion: { (POPAnimation, Bool)
in
})
}
}
Last here is my hierchy and options: (my view's name is emailLoginVCView). Also when I was debugging when I clicked another textfield I set a breakpoint so I got this info: enter image description here
I have a constraint that binds the center of the login view with the center of the main screen
when I create the AnimationEngine,I pass it that constraint, and it sets its constant to be the offScreenRightPosition.x
when I bring up the email login sheet, I'm not changing the constant of the constraint; I'm just changing the position of the view
which means that autolayout thinks it’s supposed to still be offscreen
when the second textfield becomes active, that’s somehow triggering auto-layout to re-evaluate the constraints, and it sees that the login view’s position doesn’t match what the constraint says it should be so....
Autolayout moves it offscreen
So if I add this in emailTapped(_:), the problem goes away :)
#IBAction func emailTapped(_ sender: AnyObject) {
AnimationEngine.animateToPosisition(emailLoginVCView, position: AnimationEngine.screenCenterPosition, completion: { (POPAnimation, Bool)
in
self.emailLoginVCViewConstraint.constant = 0
})
}

Counting up/down numbers animation

I have an UIPageViewController with a number in the center of each VC in it.
I want that when I swipe from view to view, the number will begin at 0 and count up until it gets to the correct number (or if the number is negative - count down) like in this gif:
https://d13yacurqjgara.cloudfront.net/users/345970/screenshots/2126044/shot.gif
How can I do that?
Thank you!
You can use NSTimer to achieve this.
Here is example project I created for you.
Create layout like this:
Then in your ViewController do like so:
import UIKit
class ViewController: UIViewController {
#IBOutlet var countingLabel: UILabel!
var number = 0
var destinationNumber = 30
var timer: NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startButtonTapped(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "countUp", userInfo: nil, repeats: true)
}
func countUp() {
if number < destinationNumber {
number += 1
countingLabel.text = "\(number)"
} else {
timer.invalidate()
}
}
}
It will work.
Do not overcomplicate with timers and invalidations, etc.
extension UILabel {
func countAnimation(upto: Double) {
let from: Double = text?.replace(string: ",", replacement: ".").components(separatedBy: CharacterSet.init(charactersIn: "-0123456789.").inverted).first.flatMap { Double($0) } ?? 0.0
let steps: Int = 20
let duration = 0.350
let delay = duration / Double(steps)
let diff = upto - from
for i in 0...steps {
DispatchQueue.main.asyncAfter(deadline: .now() + delay * Double(i)) {
self.text = "\(from + diff * (Double(i) / Double(delay)))"
}
}
}
}

How to disable gesture control in cvcalendar swift

I am using CVCalendar to display calendar . I want to disable the swipe action in the calendar view. how it is possible?
Following code which calls cvcalendar and displays calendar. I had two buttons and nex and prev to change month view.
import UIKit
class CalendarViewController: UIViewController {
#IBOutlet weak var menuView: CVCalendarMenuView!
#IBOutlet weak var calendarView: CVCalendarView!
#IBOutlet weak var monthLabel: UILabel!
#IBOutlet weak var eventTableView: UITableView!
var event : String = "1"
var shouldShowDaysOut = true
var animationFinished = true
override func viewDidLoad() {
super.viewDidLoad()
monthLabel.text = CVDate(date: NSDate()).globalDescription
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
calendarView.commitCalendarViewUpdate()
menuView.commitMenuViewUpdate()
}
}
/*
* CVCalendar library functions to display calender and events
*/
extension CalendarViewController: CVCalendarViewDelegate , MenuViewDelegate {
func presentationMode() -> CalendarMode {
return .MonthView
}
func firstWeekday() -> Weekday {
return .Sunday
}
func shouldShowWeekdaysOut() -> Bool {
return false
}
func didSelectDayView(dayView: CVCalendarDayView) {
let date = dayView.date
if dayView.isCurrentDay {
eventTableView.hidden = false
eventTableView.reloadData()
}
else {
eventTableView.hidden = true
}
println("\(calendarView.presentedDate.commonDescription) is selected!")
}
func presentedDateUpdated(date: CVDate) {
if monthLabel.text != date.globalDescription && self.animationFinished {
let updatedMonthLabel = UILabel()
updatedMonthLabel.textColor = monthLabel.textColor
updatedMonthLabel.font = monthLabel.font
updatedMonthLabel.textAlignment = .Center
updatedMonthLabel.text = date.globalDescription
updatedMonthLabel.sizeToFit()
updatedMonthLabel.alpha = 0
updatedMonthLabel.center = self.monthLabel.center
let offset = CGFloat(48)
updatedMonthLabel.transform = CGAffineTransformMakeTranslation(0, offset)
updatedMonthLabel.transform = CGAffineTransformMakeScale(1, 0.1)
UIView.animateWithDuration(0.35, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.animationFinished = false
self.monthLabel.transform = CGAffineTransformMakeTranslation(0, -offset)
self.monthLabel.transform = CGAffineTransformMakeScale(1, 0.1)
self.monthLabel.alpha = 0
updatedMonthLabel.alpha = 1
updatedMonthLabel.transform = CGAffineTransformIdentity
}) { _ in
self.animationFinished = true
self.monthLabel.frame = updatedMonthLabel.frame
self.monthLabel.text = updatedMonthLabel.text
self.monthLabel.transform = CGAffineTransformIdentity
self.monthLabel.alpha = 1
updatedMonthLabel.removeFromSuperview()
}
self.view.insertSubview(updatedMonthLabel, aboveSubview: self.monthLabel)
}
}
func topMarker(shouldDisplayOnDayView dayView: CVCalendarDayView) -> Bool {
return false
}
func dotMarker(shouldShowOnDayView dayView: CVCalendarDayView) -> Bool {
let day = dayView.date.day
if dayView.isCurrentDay{
return true
}
return false
}
func dotMarker(colorOnDayView dayView: CVCalendarDayView) -> [UIColor] {
let day = dayView.date.day
let color = UIColor.greenColor()
return [color]
}
func dotMarker(shouldMoveOnHighlightingOnDayView dayView: CVCalendarDayView) -> Bool {
return false
}
}
// MARK: - CVCalendarViewAppearanceDelegate
extension CalendarViewController: CVCalendarViewAppearanceDelegate {
func dayLabelPresentWeekdayInitallyBold() -> Bool {
return true
}
func spaceBetweenDayViews() -> CGFloat {
return 2
}
}
#IBAction func next(sender: AnyObject) {
calendarView.loadNextView()
}
#IBAction func previous(sender: AnyObject) {
calendarView.loadPreviousView()
}
You can disable scrolling of CVCalendarView this way:
Go to CVCalendarContentViewController.swift then find the extension CVCalendarContentViewController.
In that extension change the size of scrollView by replacing this line:
scrollView.contentSize = CGSizeMake(frame.size.width * 3, frame.size.height)
With this line of code:
scrollView.contentSize = CGSizeMake(frame.size.width, frame.size.height)
Hope it will help.
UPDATE:
Go to the project navigator the click on third icon which is Find Navigator as shown in below Image:
And search this line into that textField:
scrollView.contentSize = CGSizeMake(frame.size.width * 3, frame.size.height)
And your result will be like this:
Click on that result and replace that line with this line:
scrollView.contentSize = CGSizeMake(frame.size.width, frame.size.height)

Resources