1. Create a new directory for third-party frameworks, for example, /Volumes/Data/Workspace/Frameworks
2. Copy the *.framework file to the new directory
3. Add the new directory to the Xcode's "Framework Search Paths" setting
4. Add the framework to the project in Xcode by select the project in Project Navigator > General > Linked Frameworks and Libraries then click on the plus sign and browse to the framework.
Note that I used Xcode 9 to test it.
References
https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Tasks/IncludingFrameworks.html
Thursday, March 14, 2019
Tuesday, March 12, 2019
Rounded Corner UIButton
I'm developing a pet project and I want to display the buttons with rounded corners as shown in the image below.
I subclassed the UIButton and override the layoutSubviews() method as following:
https://www.hackingwithswift.com/example-code/calayer/what-is-calayer
I subclassed the UIButton and override the layoutSubviews() method as following:
public override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = 0.1 * bounds.size.width
}
Concepts
Layers
Each view in Swift has one root layer, which might contain one or more sub layers. Layers are used to draw and animate the view's contents.Corner Radius
The images below explain what the corner radius is. The longer the corner radius, the bigger rounded corner.References
https://developer.apple.com/documentation/quartzcore/calayerhttps://www.hackingwithswift.com/example-code/calayer/what-is-calayer
Handling Swipe Gesture in Swift
I'm developing a pet project and i need to swipe the screen left or right to switch between subviews as shown in the image below.
The swipe gesture recognizer was added for the container view of those buttons. The buttons will detect the finger movement and propagate the event to their parent view. The parent/container view will call the handler method, swipeGestureHandler(_:), for the swipe event.
The handler method must be marked with @objc.
1. Add the following lines to the ViewController's viewDidLoad() method
let right = UISwipeGestureRecognizer()
right.direction = .right
right.addTarget(self, action: #selector(swipeGestureHandler(_:)))
buttonsContainerView.addGestureRecognizer(right)
let left = UISwipeGestureRecognizer()
left.direction = .left
left.addTarget(self, action: #selector(swipeGestureHandler(_:)))
buttonsContainerView.addGestureRecognizer(left)
The swipe gesture recognizer was added for the container view of those buttons. The buttons will detect the finger movement and propagate the event to their parent view. The parent/container view will call the handler method, swipeGestureHandler(_:), for the swipe event.
2. Add the event handler method
@objc public func swipeGestureHandler(_ gestureRecognizer:UISwipeGestureRecognizer) {
if gestureRecognizer.state == .ended
&& gestureRecognizer.numberOfTouchesRequired == 1 {
if gestureRecognizer.direction == .right {
slideInAdvancedOperationsView()
} else if gestureRecognizer.direction == .left {
slideInBasicOperationsView()
}
}
}
The handler method must be marked with @objc.
Monday, March 11, 2019
Slide-in Subview in Swift
I'm developing a pet project, and I want to make a slide-in subview as shown in the image below.
The historyPopup view is loaded from a nib file in viewDidLoad() method. The historyPopupBackground is just a custom UIView with a transparent black background and is initialized in viewDidLoad() as well. Read here to understand what CGAffineTransform is for.
1. Adding the slide-in view and animate it
@IBAction func historyButtonTouched(_ sender: HistoryButton) {
if historyPopupHidden() {
buttonsStackView.addSubview(historyPopupBackground!) // add and bring to front
historyPopupBackground?.leadingAnchor.constraint(equalTo: buttonsStackView.leadingAnchor).isActive = true
historyPopupBackground?.trailingAnchor.constraint(equalTo: buttonsStackView.trailingAnchor).isActive = true
historyPopupBackground?.topAnchor.constraint(equalTo: buttonsStackView.topAnchor).isActive = true
historyPopupBackground?.bottomAnchor.constraint(equalTo: buttonsStackView.bottomAnchor).isActive = true
historyPopupBackground?.translatesAutoresizingMaskIntoConstraints = false
buttonsStackView.addSubview(historyPopup!) // add and bring to front
historyPopup?.leadingAnchor.constraint(equalTo: buttonsStackView.leadingAnchor).isActive = true
historyPopup?.topAnchor.constraint(equalTo: buttonsStackView.topAnchor).isActive = true
historyPopup?.bottomAnchor.constraint(equalTo: buttonsStackView.bottomAnchor).isActive = true
historyPopup?.widthAnchor.constraint(equalToConstant: 280).isActive = true
historyPopup?.translatesAutoresizingMaskIntoConstraints = false
let tx = (historyPopup?.frame.width)!
historyPopup?.transform = CGAffineTransform(translationX: -1 * tx, y: 0)
UIView.animate(withDuration: 0.3, animations: {
self.historyPopup?.transform = (self.historyPopup?.transform.translatedBy(x: tx, y: 0))!
})
} else {
hideHistoryPopup()
}
}
The historyPopup view is loaded from a nib file in viewDidLoad() method. The historyPopupBackground is just a custom UIView with a transparent black background and is initialized in viewDidLoad() as well. Read here to understand what CGAffineTransform is for.
2. Removing the subview
private func hideHistoryPopup() {
let tx = (historyPopup?.frame.width)!
UIView.animate(withDuration: 0.3, animations: {
self.historyPopup?.transform = (self.historyPopup?.transform.translatedBy(x: -1 * tx, y: 0))!
}, completion: { (finished: Bool) in
if finished {
self.historyPopup?.removeFromSuperview()
self.historyPopupBackground?.removeFromSuperview()
}
})
}
Sunday, March 10, 2019
Download entire website like Apple's Developer Documentation on MacOS
1). Download and install SiteSucker application (the app is working fine on MacOS Sierra)
2). Open the app and click on the Settings icon then select Path pane and Paths to Exclude
3). Paste the following URLs (contains regular expressions) in the listbox
The URL patterns above allows me to download https://developer.apple.com/documentation/swift and any necessary resource files (JS, CSS, images, etc.) under or outside the directory. It won't download the other URLs such as:
2). Open the app and click on the Settings icon then select Path pane and Paths to Exclude
3). Paste the following URLs (contains regular expressions) in the listbox
https://developer.apple.com/documentation/[a-rt-z].*
https://developer.apple.com/documentation/s[a-vx-z].*
4). Check the "Use Regular Expressions" checkboxThe URL patterns above allows me to download https://developer.apple.com/documentation/swift and any necessary resource files (JS, CSS, images, etc.) under or outside the directory. It won't download the other URLs such as:
https://developer.apple.com/documentation/foundation
https://developer.apple.com/documentation/mapkit
https://developer.apple.com/documentation/uikit
https://developer.apple.com/documentation/gamekit
Saturday, March 9, 2019
Copy, Cut, and Paste Operations using Swift
Copy a string to the pasteboard
1). Write data to the pasteboard programmatically
UIPasteboard.general.setValue("hello", forPasteboardType: "public.plain-text")
2). Open another app for example, Google Chrome browser, and touch the address bar twice to show the edit menu (copy, cut, and paste commands). Then, touch Paste.Concepts
Pasteboard
UTI (Uniform Type Identifier)
UTI is a string to identify a class of entities (documents, pasteboard data, and bundles). UTI replaces the incompatible existing methods of tagging data. Currently, for example, a JPEG file is identified by any of the following methods:
1. A four character type code of JPEG
2. A filename extension of .jpg
3. A filename extension of .jpeg
4. A MIME type of image/jpeg
With UTI, the data is identified by the string public.jpeg. Then, we can use a utility function to translate from one to the other.
The key advantage of UTI over the other tagging methods is a conformance hierarchy. For example, the UTI public.html, which defines HTML text, conforms to the base text identifier, public.text. In this case, conformance lets applications which can open the general text files identify HTML files as ones i can open as well.
References
https://developer.apple.com/library/archive/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/UsingCopy,Cut,andPasteOperations/UsingCopy,Cut,andPasteOperations.html#//apple_ref/doc/uid/TP40009542-CH11-SW21
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html#//apple_ref/doc/uid/TP40001319-CH202-CHDHIJDE
Friday, March 8, 2019
Swift Error: nib must contain exactly one top level object which must be a UITableViewCell instance
I'm developing a pet project, which requires loading a UITableViewCell from a XIB file. At first, it worked fine but after making some changes, I got the error when the system trying to load the UITableViewCell from a nib file to construct the UITableView object.
It's because I accidentally dragged a Tap Gesture Recognizer from the Object Library and dropped it on the UITableViewCell in IB.
Click on the Tap Gesture Recognizer icon and press Delete key.
Cause
It's because I accidentally dragged a Tap Gesture Recognizer from the Object Library and dropped it on the UITableViewCell in IB.
Solution
Click on the Tap Gesture Recognizer icon and press Delete key.
Subscribe to:
Posts (Atom)










