Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for iOS 13 Dark Mode #97

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

leonluc-dev
Copy link
Contributor

This PR is to add support for the new iOS 13 Dark mode.

Changes made:

  • Changed color references to dynamic iOS 13 colors (with #available check for iOS 12 and earlier support)

  • Default color assignment in initializer moved to functions so availability check can be applied

Changed color references to dynamic iOS 13 colors (with #available check for iOS 12 and earlier support)
Default color assignment moved to functions so availability check can be applied
@YagbhanSingh
Copy link

YagbhanSingh commented Jan 10, 2020

Added support for iOS 13 Dark mode with bug fixes in datepickerdialog ios #97
changes :

  1. dialog view frame changes issue resolved .
  2. dark mode bug fixes.

Support for iOS 13 Dark mode with bug fixes #97

`//
// DatePickerDialog.swift
//
//
// Created by Yagbhan Singh on 10/01/20.
// Copyright © 2020 Yagbhan Singh. All rights reserved.
//

import Foundation
import UIKit

private extension Selector {
static let buttonTapped = #selector(DatePickerDialog.buttonTapped)
static let deviceOrientationDidChange = #selector(DatePickerDialog.deviceOrientationDidChange)
}

public class DatePickerDialog: UIView {
public typealias DatePickerCallback = (_ date: Date?) -> Void

// MARK: - Constants
private let kDatePickerDialogDefaultButtonHeight:       CGFloat = 50
private let kDatePickerDialogDefaultButtonSpacerHeight: CGFloat = 1
private let kDatePickerDialogCornerRadius:              CGFloat = 7
private let kDatePickerDialogDoneButtonTag:             Int     = 1

// MARK: - Views
public var dialogView:   UIView!
public var dialogContainer:   UIView!


private var titleLabel:   UILabel!
public var datePicker:    UIDatePicker!
private var cancelButton: UIButton!
private var doneButton:   UIButton!
private var linelbl: UILabel!

// MARK: - Variables
private var defaultDate:    Date?
private var datePickerMode: UIDatePicker.Mode?
private var callback:       DatePickerCallback?

// MARK: - Dialog initialization
override init(frame: CGRect) {
    super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
    setupView()
}

required public init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


func setupView() {
    self.dialogView = createContainerView()

    self.dialogView!.layer.shouldRasterize = true
    self.dialogView!.layer.rasterizationScale = UIScreen.main.scale

    self.layer.shouldRasterize = true
    self.layer.rasterizationScale = UIScreen.main.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!)
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.CheckHeaderanimation1), name: NSNotification.Name(rawValue: "receivedatefinal"), object: nil)

}

/// Create the dialog view, and animate opening the dialog
public func show(title: String, doneButtonTitle: String = "Done", cancelButtonTitle: String = "Cancel", defaultDate: Date = Date(), minimumDate: Date? = nil, maximumDate: Date? = nil, datePickerMode: UIDatePicker.Mode = .date, callback: @escaping DatePickerCallback) {
    self.titleLabel.text = title
   // self.titleLabel.textColor = UIColor.black
    self.doneButton.setTitle(doneButtonTitle, for: .normal)
    self.cancelButton.setTitle(cancelButtonTitle, for: .normal)
    self.datePickerMode = datePickerMode
    self.callback = callback
    
    self.datePicker.addTarget(self, action: #selector(self.datePickerValueChanged), for: UIControl.Event.valueChanged)
    self.datePicker.timeZone = NSTimeZone.local
    self.datePicker.datePickerMode = self.datePickerMode ?? .date
  
  
    let currentDate = Date()
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
     formatter.locale = Locale.init(identifier: "en_GB")
    let datepickerdate  = formatter.string(from: currentDate) as NSString
    
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd HH:mm:ss"
     df.locale = Locale.init(identifier: "en_GB")
    let date = df.date(from: datepickerdate as String)
    if let unwrappedDate = date {
        self.datePicker.setDate(unwrappedDate, animated: false)
        self.datePicker.maximumDate = unwrappedDate
    }
    
  
    self.datePicker.minimumDate = minimumDate
    
    /* Add dialog to main window */
    guard let appDelegate = UIApplication.shared.delegate else { fatalError() }
    guard let window = appDelegate.window else { fatalError() }
    window?.addSubview(self)
    window?.bringSubviewToFront(self)
    window?.endEditing(true)

    NotificationCenter.default.addObserver(self, selector: .deviceOrientationDidChange, name: UIDevice.orientationDidChangeNotification, object: nil)

    /* Anim */
    UIView.animate(
        withDuration: 0.2,
        delay: 0,
        options: .curveEaseInOut,
        animations: {
            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)
        }
    )
}


@objc func datePickerValueChanged(sender:UIDatePicker)
{
    
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    let datepickerdate  = formatter.string(from: self.datePicker.date) as NSString
    let userInfo: [AnyHashable: Any] = ["dateval": (datepickerdate)]
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "receivedate"), object: nil, userInfo: userInfo)
    
}

@objc func CheckHeaderanimation1(notification:NSNotification)
{
    var tempdect = NSDictionary ()
    tempdect = notification.userInfo! as NSDictionary
    let str = tempdect.value(forKey: "dateval1")
    self.titleLabel.text = str as? String
}

/// Dialog close animation then cleaning and removing the view from the parent
private func close() {
    NotificationCenter.default.removeObserver(self)

    let currentTransform = self.dialogView.layer.transform
    let startRotation = (self.value(forKeyPath: "layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0
    let rotation = CATransform3DMakeRotation((CGFloat)(-startRotation + .pi * 270 / 180), 0, 0, 0)
    self.dialogView.layer.transform = CATransform3DConcat(rotation, CATransform3DMakeScale(1, 1, 1))
    self.dialogView.layer.opacity = 1

    UIView.animate(
        withDuration: 0.2,
        delay: 0,
        options: [],
        animations: {
            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) in
        for v in self.subviews {
            v.removeFromSuperview()
        }

        self.removeFromSuperview()
        self.setupView()
    }
}

/// Creates the container view here: create the dialog, then add the custom content and buttons
public func createContainerView() -> UIView {
    let screenSize = countScreenSize()
    let dialogSize = CGSize(
        width: 300,
        height: 250
            + kDatePickerDialogDefaultButtonHeight
            + kDatePickerDialogDefaultButtonSpacerHeight)

    // For the black background
    self.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)

    // This is the dialog's container; we attach the custom content and the buttons to this one
    dialogContainer = UIView(frame: CGRect(x: (screenSize.width - dialogSize.width) / 2, y: (screenSize.height - dialogSize.height) / 2, width: 300, height: 300))
    if #available(iOS 13.0, *) {
        dialogContainer.backgroundColor = .systemBackground
    } else {
        // Fallback on earlier versions
    }

    dialogContainer.layer.cornerRadius = 7.0
    dialogContainer.layer.borderWidth = 1.0
    dialogContainer.layer.masksToBounds = true
    dialogContainer.layer.borderColor = UIColor.lightGray.cgColor

    if #available(iOS 13.0, *){
               dialogContainer.layer.borderColor = UIColor.systemGray3.cgColor
          }
          else{
              dialogContainer.layer.borderColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1).cgColor
          }
    dialogContainer.layer.borderWidth = 1
    dialogContainer.layer.shadowRadius = 7 + 5
    dialogContainer.layer.shadowOpacity = 0.1
    dialogContainer.layer.shadowOffset = CGSize(width: 0 - (7 + 5) / 2, height: 0 - ( 7 + 5) / 2)
    dialogContainer.layer.shadowColor = UIColor.lightGray.cgColor
    dialogContainer.layer.shadowPath = UIBezierPath(roundedRect: dialogContainer.bounds, cornerRadius: dialogContainer.layer.cornerRadius).cgPath

    // There is a line above the button
    let lineView = UIView(frame: CGRect(x: 0, y: dialogContainer.bounds.size.height - kDatePickerDialogDefaultButtonHeight - kDatePickerDialogDefaultButtonSpacerHeight, width: dialogContainer.bounds.size.width, height: kDatePickerDialogDefaultButtonSpacerHeight))
    if #available(iOS 13.0, *){
        lineView.backgroundColor =  UIColor.systemGray3
    }
    else{
        lineView.backgroundColor =  UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1)
    }
    dialogContainer.addSubview(lineView)

    //Title
    self.titleLabel = UILabel(frame: CGRect(x: 10, y: 15, width: 280, height: 30))
    self.titleLabel.textAlignment = .center
    self.titleLabel.font = UIFont.boldSystemFont(ofSize: 21)
    self.titleLabel.textColor = UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1)
    dialogContainer.addSubview(self.titleLabel)
    
    self.linelbl = UILabel(frame: CGRect(x: 0, y: 50, width: 300, height: 2))
    //self.linelbl.textAlignment = .left
    //self.linelbl.font = UIFont.boldSystemFont(ofSize: 21)
    self.linelbl.backgroundColor = UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1)
    dialogContainer.addSubview(self.linelbl)
    
    

    self.datePicker = UIDatePicker(frame: CGRect(x: 0, y: 30, width: 0, height: 0))
    self.datePicker.autoresizingMask = .flexibleRightMargin
    self.datePicker.frame.size.width = 300
    self.datePicker.frame.size.height = 250
    dialogContainer.addSubview(self.datePicker)

    // Add the buttons
    addButtonsToView(container: dialogContainer)

    return dialogContainer
}

/// Add buttons to container
private func addButtonsToView(container: UIView) {
    let buttonWidth = container.bounds.size.width / 2

    self.cancelButton = UIButton(type: .custom) as UIButton
    self.cancelButton.frame = CGRect(
        x: 0,
        y: container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
        width: buttonWidth,
        height: kDatePickerDialogDefaultButtonHeight
    )
    self.cancelButton.setTitleColor(UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1), for: .normal)
    self.cancelButton.setTitleColor(UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1), for: .highlighted)
    self.cancelButton.titleLabel!.font = UIFont.boldSystemFont(ofSize: 18)
    self.cancelButton.layer.cornerRadius = kDatePickerDialogCornerRadius
    self.cancelButton.addTarget(self, action: .buttonTapped, for: .touchUpInside)
    container.addSubview(self.cancelButton)

    self.doneButton = UIButton(type: .custom) as UIButton
    self.doneButton.frame = CGRect(
        x: buttonWidth,
        y: container.bounds.size.height - kDatePickerDialogDefaultButtonHeight,
        width: buttonWidth,
        height: kDatePickerDialogDefaultButtonHeight
    )
    self.doneButton.tag = kDatePickerDialogDoneButtonTag
    self.doneButton.setTitleColor(UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1), for: .normal)
    self.doneButton.setTitleColor(UIColor(red: 99/255, green: 182/255, blue: 225/255, alpha: 1), for: .highlighted)
    self.doneButton.titleLabel!.font = UIFont.boldSystemFont(ofSize: 18)
    self.doneButton.layer.cornerRadius = kDatePickerDialogCornerRadius
    self.doneButton.addTarget(self, action: .buttonTapped, for: .touchUpInside)
    container.addSubview(self.doneButton)
}

@objc func buttonTapped(sender: UIButton!) {
    if sender.tag == kDatePickerDialogDoneButtonTag {
        self.callback?(self.datePicker.date)
    } else {
        self.callback?(nil)
    }

    close()
}

// MARK: - Helpers

/// Count and return the screen's size
func countScreenSize() -> CGSize {
    let screenWidth = UIScreen.main.bounds.size.width
    let screenHeight = UIScreen.main.bounds.size.height

    return CGSize(width: screenWidth, height: screenHeight)
}

}
`

@leonluc-dev leonluc-dev mentioned this pull request Jul 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants