Skip to content

Instantly share code, notes, and snippets.

@Erkened
Last active September 28, 2017 13:48
Show Gist options
  • Select an option

  • Save Erkened/35ce3189552a67a0c94f to your computer and use it in GitHub Desktop.

Select an option

Save Erkened/35ce3189552a67a0c94f to your computer and use it in GitHub Desktop.
Snippets of Swift code I reuse often
/*
// TO APPLY DIFFERENT STRINGS FROM VARIANTS.STRINGS RATHER THAN LOCALIZABLE.STRINGS
var localised:String
{
return Bundle.main.localizedString(forKey:self, value:Bundle.main.localizedString(forKey:self, value:nil, table:nil), table:"variants")
}
// TO CONTROL THE LINE HEIGHT OF AN ATTRIBUTED STRING (LIKE TAB BAR BUTTONS)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 6
paragraphStyle.alignment = .center
myMutableString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range: NSRange(location:0,length:myMutableString.length))
// TO CLONE A REPOSITORY FROM ONE REMOTE TO ANOTHER (source: https://stackoverflow.com/questions/7818927/git-push-branch-from-one-remote-to-another)
git remote add origin2 ssh://[email protected]/blabla.git
git push origin2 refs/remotes/origin/*:refs/heads/* // This pushes all the branches from origin to origin2
git push origin2 refs/tags/*:refs/tags/* // This pushes all the tags from origin to origin2
// TO ENABLE DRAG AND DROP BETWEEN TWO TABLES
https://www.hackingwithswift.com/whats-new-in-ios-11?utm_campaign=This%2BWeek%2Bin%2BSwift&utm_medium=email&utm_source=This_Week_in_Swift_134
// TO SWITCH WHAT XCODEVERSION TO BUILD
xcode-select --print-path
/Applications/Xcode.app/Contents/Developer
/Users/john/Desktop/XCode 7/Xcode.app/Contents/Developer
Then to change it just run
sudo xcode-select --switch <path-to-beta-xcode>/Contents/Developer
// TO CHANGE WHAT SWIFT VERSION COMPILES CARTHAGE
Source http://stackoverflow.com/questions/37867753/change-carthage-swift-version
xcrun swift -version
carthage update --platform iOS --no-use-binaries
Source http://stackoverflow.com/questions/40250381/module-compiled-with-swift-3-0-cannot-be-imported-in-swift-3-0-1
// USE PRIVATE(SET) TO MAKE SETTING PRIVATE, BUT KEEPING GET PUBLIC
"private" to keep it local to a source file, "internal" to keep it local to the module/project.
private(set) only makes the set private. Private makes both set and get functions private
// INSTEAD OF GUARD LET - ASSIGN VAR - GUARD LET STRUCTURE, USE 1 GUARD LET THROUGHOUT BY WRAPPING VAR INTO AN OPTIONAL
// Source: https://appventure.me/2016/04/14/force-optionals-in-guard-or-let-optional-binding/
func example() {
guard let array = someArray(),
numberThree = Optional.Some(array[2])
where numberThree == 3
else { return }
print(numberThree)
}
// FUNCTORS, MONADS AND APPLICATIVES EXPLAINED
// Source: http://www.russbishop.net/monoids-monads-and-functors
Functors are containers you can call map on. That's it. Seriously.
Applicative lets you stuff the function itself inside a container, otherwise it's almost identical to Functors.
Monads are containers you can call flatMap on. Again, that's it.
// Keep an eye on https://thatthinginswift.com/
// Remember that Optional are an Enum type with .Some(T) and .None, which means we can do this to test if an optional
// holds a value:
// Source: https://thatthinginswift.com/switch-unwrap-shortcut/
switch (self.textValidation, self.passwordValidation) {
case (.Some, .Some):
print("both look good!")
default:
print("something was nil...")
}
// HOW-TO: PUSH NOTIFICATIONS
https://thatthinginswift.com/remote-notifications/
http://www.fantageek.com/blog/2016/04/15/push-notification-in-practice/
// HOW TO PROPERLY UPDATE THE LAYOUT WHEN A CHANGE NEEDS TO HAPPEN
// layoutIfNeeded is called immediately, setNeedsLayout changed the UI in the next update cycle
// Source: http://www.iosinsight.com/setneedslayout-vs-layoutifneeded-explained/
// Update the frame in case anything needed to be redrawn
view.layoutIfNeeded()
// Change whatever constraints need updating
someview.blueHeight.constant = 25.0
// Animate and capture the redrawing phase in the block
UIView.animateWithDuration(2.0) {
self.view.layoutIfNeeded()
}
// EXTENSION TO FIND KEYS BY VALUE
// Source: https://ijoshsmith.com/2016/04/14/find-keys-by-value-in-swift-dictionary/
extension Dictionary where Value: Equatable {
/// Returns all keys mapped to the specified value.
/// ```
/// let dict = ["A": 1, "B": 2, "C": 3]
/// let keys = dict.keysForValue(2)
/// assert(keys == ["B"])
/// assert(dict["B"] == 2)
/// ```
func keysForValue(value: Value) -> [Key] {
return flatMap { (key: Key, val: Value) -> Key? in
value == val ? key : nil
}
}
}
// EXTENSION TO INCREASE THE TAPPABLE AREA OF A BUTTON
// Source: http://www.sthoughts.com/2015/04/25/swift-expand-uibuttons-clickable-area/
extension UIButton {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let relativeFrame = self.bounds
let hitTestEdgeInsets = UIEdgeInsetsMake(-44, -44, -44, -44)
let hitFrame = UIEdgeInsetsInsetRect(relativeFrame, hitTestEdgeInsets)
return hitFrame.contains(point)
}
}
// SORTING EXPLAINED
// Source: https://thatthinginswift.com/sort-and-sorted/
// TO ROLL BACK TO A PREVIOUS COMMIT IN GIT
git status // Checks the status of the current branch. Use git checkout branchname to change branch
git reset --hard 582acd2 // Resets back to the commit number 582acd2
git push --force // Pushes this commit on top of everything
git pull // Makes sure the branch is up to date
// TO REMOVE THE STATUS BAR
// Set ViewController-based status bar appearance to NO in info.plist
// Set hide status bar in the project > general
// EXECUTE CODE IN A BACKGROUND THREAD
https://www.hackingwithswift.com/read/9/3/gcd-101-dispatch_async
// CATCH A THROWN ERROR IN A CLOSURE (AND MORE COOL STUFF TO KNOW)
http://appventure.me/2015/06/19/swift-try-catch-asynchronous-closures/
// NIL COALESCING OPERATOR
a ?? b
is the same as
a != nil ? a! : b
// TO CREATE AN ENUM THAT TRANSLATES TO STRING
enum SentBy : String {
case User = "MessageSentByUser"
case Opponent = "MessageSentByOpponent"
}
// TO HIDE THE STATUS BAR IN ALL THE UIVIEWCONTROLLERS
// In info.plist add 2 keys:
// View controller-based status bar appearance : NO
// Status bar is initially hidden : YES
// TO RESET THE NAVIGATION STACK
func resetNavigationStack(viewController:UIViewController){
if let navigationController = viewController.navigationController{
var navigationArray = navigationController.viewControllers
navigationArray.removeAll()
navigationArray.append(viewController)
navigationController.viewControllers = navigationArray
}
else {
print("No navigation controller")
}
}
// TO ADD BANNERS INSTEAD OF INTERSTITIALS
https://twittercommunity.com/t/swift-and-banners/27025/3
// TO REMOVE WHITE SPACE BEFORE AND AFTER A STRING
testString = testString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
// TO MAKE A STRUCT EQUATABLE AND HASHABLE SO THAT IT CAN BE ADDED TO DICTIONARIES ETC. // Source: http://kelan.io/2015/swift-hashable-for-sets/
struct S {
let i: Int
let str: String
}
extension S: Hashable, Equatable {
var hashValue: Int { return i.hashValue ^ str.hashValue }
}
func ==(lhs: S, rhs: S) -> Bool {
return lhs.i == rhs.i && lhs.str == rhs.str
}
// TO MAKE A STRUCT EQUATABLE SO THAT IT CAN BE USED WITH FIND, COMPARISON ETC. // Source: http://kelan.io/2015/swift-equatable-structs/
struct ExampleStruct{
var ID = ""
var title = ""
}
extension ExampleStruct: Equatable {}
func ==(lhs: ExampleStruct, rhs: ExampleStruct) -> Bool {
return lhs.ID == rhs.ID && lhs.title == rhs.title
}
// LOCAL NOTIFICATIONS
// BROADCAST (No object)
NSNotificationCenter.defaultCenter().postNotificationName("toggleMode", object: nil)
// BOADCAST (With object)
NSNotificationCenter.defaultCenter().postNotificationName("showProductDetails", object: nil, userInfo: ["productID":productID])
// LISTEN
// In ViewDidLoad
NSNotificationCenter.defaultCenter().addObserver(self, selector: "toggleMode", name: "toggleMode", object: nil)
// If the notification comes with userInfo
func showProductDetails(notification:NSNotification){
guard let userInfo:[String:AnyObject] = notification.userInfo as? [String:AnyObject] else{
print("user info received incorrect")
return
}
// Do whatever
}
// In Deinit
// Remove self from receiving any notification
NSNotificationCenter.defaultCenter().removeObserver(self)
// TO CREATE A FUNCTION WITH A BLOCK
func fillDictionaries(completion: (result:Bool) -> Void){
// Do your thing
completion(true)
}
// IF LOCALIZATION DOESN'T WORK
Uninstall the app and reinstall it...
// TO USE SPECIAL CHARACTERS, LIKE THE ONES IN FONTELLO
var font = UIFont(name: "fontello", size: 22.0)
queueButton.setTitle("\u{E801}", forState: .Normal)
queueButton.titleLabel?.font = font!
// TO DISABLE SCROLLING IN A UIPAGEVIEWCONTROLLER
//pageViewController.dataSource = self // Scrolling disabled when no data source
// TO DISMISS THE KEYBOARD IF TAPPED OUTSIDE THE UITEXTFIELDS
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
yourTextField.resignFirstResponder()
}
// HOW TO USE THE DELEGATION PATTERN
- In parentViewController:
class ParentViewController: UIViewController, ChildViewControllerDelegate{
override func viewDidLoad(){
super.viewDidLoad()
ChildViewControllerDelegate = self
}
func doSomething(){
println("I did something!")
}
}
- In childViewController:
protocol ChildViewControllerDelegate{
func doSomething()
}
class ChildViewController: UIViewController{
var tellDelegateTo:ChildViewControllerDelegate?
func doSomethingElse(){
if let tellDelegateTo = tellDelegateTo {
tellDelegateTo.doSomething()
}
}
}
// TO FIT A LABEL WITHIN A CERTAIN WIDTH
font = UIFont(name: "OpenSans-SemiBold", size: 18.0)
MainTopBarViewControllerVariables.titleLabel.textColor = ColourConstants.wildSand
MainTopBarViewControllerVariables.titleLabel.textAlignment = .Center
MainTopBarViewControllerVariables.titleLabel.font = font!
MainTopBarViewControllerVariables.titleLabel.adjustsFontSizeToFitWidth = true // Needed to shrink down the text to the right size
MainTopBarViewControllerVariables.titleLabel.baselineAdjustment = UIBaselineAdjustment.AlignCenters // Needed to vertically center the shrinked text into its bounding box
MainTopBarViewControllerVariables.titleLabel.minimumScaleFactor = 0.1 // How small the text can get
MainTopBarViewControllerVariables.titleLabel.text = "Test"
// TO RETRIEVE THE LIST OF FONTS AND THEIR NAMES IN APP.DELEGATE
for family in UIFont.familyNames(){
println(family)
for name in UIFont.fontNamesForFamilyName(family as! String){
println(" \(name)")
}
}
// TO MODIFY THE TARGET OF A BUTTON IN ANOTHER CLASS
TopViewVariables.peersButton.removeTarget(TopViewVariables.peersButton.superview, action: "showPeers", forControlEvents: .TouchUpInside)
// SINGLETON >= IOS 8.3 / SWIFT 1.2
//static let sharedInstance = P2PBrain() // Makes it a Singleton
// TO GET THE ROOT VIEW CONTROLLER (not safe)
let rootViewController: UIViewController = UIApplication.sharedApplication().windows[0].rootViewController!!
// TO EXECUTE AN ACTION AFTER A CERTAIN AMOUNT OF TIME
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
// TO CENTER THE TEXT IN A UITEXTVIEW (RE-INIT IF SEGUED AWAY!)
func centreTextInTextView(textViewToCenter:UITextView){
// Change the offset based on the content
var topCorrect:CGFloat = (textViewToCenter.bounds.size.height - textViewToCenter.contentSize.height)/2
topCorrect = topCorrect < 0.0 ? 0.0 : topCorrect
textViewToCenter.contentOffset = CGPoint(x: 0, y: -topCorrect)
}
// GETTING THE BIGGEST POSSIBLE VALUE FOR UINT64 FOR EXAMPLE
var maxID:NSNumber = NSNumber(unsignedLongLong: UINT64_MAX)
// MAX FUNCTION EMBEDDED IN SWIFT
let numbers = [ 1, 42, 5, 21 ]
var maxNumber = 0
for number in numbers {
maxNumber = max(maxNumber, number as Int)
}
print("the max number is \(maxNumber)") // will be 42
// TO GET A TABLE TO BEHAVE WHEN DISPLAYING DIFFERENT ROW HEIGHTS AND SEGUEING TO OTHER VIEWS
http://stackoverflow.com/questions/27684525/is-there-a-way-to-make-estimated-row-heights-with-uitableview-actually-work-with/28931606#28931606
TO RETRIEVE A PICTURE FROM AN URL
let url = NSURL(string: image.url)
let data = NSData(contentsOfURL: url!) //make sure your image in this url does exist, otherwise unwrap in an if let check
imageURL.image = UIImage(data: data!)
FOR THE LIST OF POTENTIAL DATE FORMATTER PATTERNS, CHECK OUT THIS LINK
http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns
TO ADD AN ARRAY AT THE BEGINNING OF ANOTHER ONE
anArray.splice(["So", "Many", "Strings"], atIndex: 0)
IF AN APP STORES A LOT OF DATA IN CORE DATA:
CHECK THE "STORE IN EXTERNAL RECORD" BOX FOR THAT SPECIFIC ATTRIBUTE IN CORE DATA. THIS WAY THE APP WON'T SHOW AS MUCH DATA USAGE IN ICLOUD > STORAGE > MANAGE STORAGE
TO DISABLE THE AUTOMATIC ICLOUD BACKUP OF SOME DATA:
func addSkipBackupAttributeToItemAtURL(URL: NSURL!) -> Bool{
assert(NSFileManager.defaultManager().fileExistsAtPath(URL.path!))
var err : NSError? = nil
var success : Bool! = URL.setResourceValue(NSNumber(bool:true), forKey: NSURLIsExcludedFromBackupKey, error: &err)
if(!success){
println("Error excluding \(URL.lastPathComponent) from backup\(err) ")
}
else {
println("Excluded \(URL.lastPathComponent) from backup :)")
}
return success
}
TO ROUND ONLY 1 OR 2 CORNERS OF A UIVIEW
autoHashtagsBG = UIView(frame: frame)
autoHashtagsBG?.backgroundColor = UIColor.blackColor()
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: autoHashtagsBG!.bounds, byRoundingCorners: [.TopRight, .TopLeft], cornerRadii: CGSize(width: 20.0, height: 20.0)).CGPath
autoHashtagsBG!.layer.mask = maskLayer
BACKGROUND/FOREGROUND THREADS (DO NOT PUT OPTIONALS INSIDE THE CLOSURE)
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// Do some background stuff
dispatch_async(dispatch_get_main_queue()) {
// Update some UI
}
}
THIS IS HOW TO USE TUPLES
var tuple = (title:String, message:String)
tuple.title = "This is a tuple"
tuple.message = "And its accompanying message"
let extractedTitle = tuple.title
TO ADD AN ELEMENT IN CORE DATA AND DO A LIGHT MIGRATION
http://jamesonquave.com/blog/core-data-migrations-swift-tutorial/
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment