-
-
Save byJeevan/da1c69a143b68585ef1d0a2f610f2a01 to your computer and use it in GitHub Desktop.
/* | |
* Author : Jeevan Rao | |
* Date : 13/0/2017 | |
* Swift : V3.1 | |
*/ | |
/* UI + UX Tricks */ | |
//Selection style of table view cell (other than Default grey / Blue/ none) | |
let selectionColorView = UIView() | |
selectionColorView.backgroundColor = UIColor.blue | |
cell.selectedBackgroundView = selectionColorView | |
//UISeachBar Cancel button color | |
UIBarButtonItem.appearance(whenContainedInInstancesOf:[UISearchBar.self]).tintColor = UIColor.white | |
//Slowdown UI Updates | |
func delay(_ delay:Double, closure:@escaping ()->()) { | |
let when = DispatchTime.now() + delay | |
DispatchQueue.main.asyncAfter(deadline: when, execute: closure) | |
} | |
/* Extensions */ | |
//Bottom border for text field | |
extension UITextField | |
{ | |
//Bottom line/border for UITextfield | |
func setBottomBorderColor(_ color:UIColor) | |
{ | |
self.borderStyle = .none; | |
let border = CALayer() | |
let width = CGFloat(1.0) | |
border.borderColor = color.cgColor | |
border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) | |
border.borderWidth = width | |
self.layer.addSublayer(border) | |
self.layer.masksToBounds = true | |
} | |
} | |
//Shadow - card effect for UIView | |
extension UIView { | |
func addDropShadowToView(){ | |
self.layer.masksToBounds = false | |
self.layer.shadowColor = UIColor.gray.cgColor; | |
self.layer.shadowOffset = CGSize(width:2.0, height:2.0) | |
self.layer.shadowOpacity = 0.75 | |
} | |
} | |
// Make ‘String’ to return its Length | |
extension String { | |
var length: Int { | |
return (self as NSString).length | |
} | |
} | |
//Will return NSAttributedString from HTML String | |
extension String{ | |
func convertHtml() -> NSAttributedString{ | |
guard let data = data(using: .utf8) else { return NSAttributedString() } | |
do{ | |
return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil) | |
}catch{ | |
return NSAttributedString() | |
} | |
} | |
} | |
myLabel.attributedText = "<b>Bolded</b>".convertHtml() //Example | |
//Gives array of unique elements from given array | |
extension Sequence where Iterator.Element: Hashable { | |
func unique() -> [Iterator.Element] { | |
var seen: [Iterator.Element: Bool] = [:] | |
return self.filter { seen.updateValue(true, forKey: $0) == nil } | |
} | |
} | |
/* Misc */ | |
//Calculates execution time of block of code. | |
let info = ProcessInfo.processInfo | |
let begin = info.systemUptime | |
//Code Stuff | |
let diff = (info.systemUptime - begin) | |
//List all the installed Fonts | |
for fontFamilyName in UIFont.familyNames{ | |
for fontName in UIFont.fontNames(forFamilyName: fontFamilyName){ | |
print("Family: \(fontFamilyName) Font: \(fontName)") | |
} | |
} | |
//RESET User Defaults (all keys) | |
let domain = Bundle.main.bundleIdentifier! | |
UserDefaults.standard.removePersistentDomain(forName: domain) | |
UserDefaults.standard.synchronize() | |
//Generate UIImage object from UIView | |
func generateImage(for view: UIView) -> UIImage? { | |
defer { | |
UIGraphicsEndImageContext() | |
} | |
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale) | |
if let context = UIGraphicsGetCurrentContext() { | |
view.layer.render(in: context) | |
return UIGraphicsGetImageFromCurrentImageContext() | |
} | |
return nil | |
} | |
//:usage | |
var iconWithTextImage: UIImage { | |
let containerView = UIView.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) | |
let icon = UIImageView.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) | |
icon.image = UIImage.init(named: "shirt.png") | |
icon.contentMode = .scaleAspectFit | |
containerView.addSubview(icon) | |
return generateImage(for: containerView) ?? UIImage() | |
} | |
//CLOSURE Callback Example | |
//Closure Callback : | |
public typealias Closure = () -> Void | |
//Definition | |
public var exitFromTap = Closure?({}) | |
//Declaration in somewhere needs a callback. | |
exitFromTap?() | |
//Usage | |
yourClass.exitFromTap = { print(“Good Bye”) } | |
/// Returns the element at the specified index iff it is within bounds, otherwise nil. | |
extension Collection { | |
subscript (safe index: Index) -> Element? { | |
return indices.contains(index) ? self[index] : nil | |
} | |
} | |
let sample = ["BMW", "Audi", "Tesla", "Fiat"] | |
sample[safe : 0] //Prints "BMW" | |
sample[safe : 4] //Prints 'nil' | |
/// String extension : replacement for' subString:' | |
extension String { | |
func slice(from: String, to: String) -> String? { | |
let fromIndex = self.index(self.index(of: from)!, offsetBy: 1) | |
let toIndex = self.index(self.index(of: to)!, offsetBy: -1) | |
return String(self[fromIndex...toIndex]) | |
} | |
} | |
//Usage : "Date(1511508780012+0530)".slice(from: "(", to: "+") | |
//Core Data - Easy & Clean way to get NSManagedContext | |
public static func getContext() -> NSManagedObjectContext { | |
let appDelegate = UIApplication.shared.delegate as! AppDelegate | |
return appDelegate.persistentContainer.viewContext | |
} | |
//Limit characters in text filed | |
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { | |
let currentCharacterCount = textField.text?.count ?? 0 | |
if (range.length + range.location > currentCharacterCount){ | |
return false | |
} | |
let newLength = currentCharacterCount + string.count - range.length | |
return newLength <= Constants.nameCharLimit | |
} |
Core Data - Easy & Clean way to get NSManagedContext :::
public static func getContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
//Limit characters in text filed
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = textField.text?.count ?? 0
if (range.length + range.location > currentCharacterCount){
return false
}
let newLength = currentCharacterCount + string.count - range.length
return newLength <= Constants.nameCharLimit
}
UIWindow has three default levels: (windowLevel)
- .normal
- .statusBar
- .alert
With .alert > .statusBar > .normal. If a more fine-grain level of control is needed it's possible to use a custom level:
window.windowLevel = .normal + 25
As of iOS 13: .alert has a raw value of 2000, .statusBar has a raw value of 1000 and .normal has a raw value of 0.
link)
-
Any UIViewController (including UINavigationControllers as UINavigationControllers are a type of UIViewControllers) presented modally must be dismissed.
-
Since UINavigationControllers hold UIViewControllers in their stack, they can present UIViewControllers both modally and via a push. When navigating away from any pushed UIViewControllers, UINavigationControllers must pop the UIViewController.
-
Though it is possible to present UIViewControllers both modally and via a push, UIViewControllers can only present other UIViewControllers. Therefore, UIViewControllers can only be dismissed (unless they are inside a UINavigationController stack and the UINavigationController is handling the pop — see lesson #2). This is why it is not possible to call popViewController on a UIViewController.
-
PresentingViewController is a property provided by Apple that is available on both UIViewControllers and UINavigationControllers. Calling presentingViewController.dismiss(animated:completion) will dismiss everything presented by the parentViewController. The parentViewController is the UIViewController that presented the current UIViewController. So, if you have a UINavigationController with 3 UIViewControllers within its stack, calling presentingViewController.dismiss(animated:completion) will dismiss both the UINavigationController and the 3 UIViewControllers held within its stack.
5.Similarly, Apple also provides another property on UIViewControllers and UINavigationControllers — presentedViewController. Calling presentedViewController.dismiss(animated:completion) will dismiss the childViewController. The childViewController is the current UIViewController that is being presented.
//Open URL
let fbAppStoreLink = URL.init(string: "https://itunes.apple.com/in/app/facebook/id284882215")!
let fbAppLinkURL = URL.init(string: "fb://page/?id=203525053017188")!