Skip to content

Instantly share code, notes, and snippets.

@thornpig
thornpig / Xcode_lldb_debug
Last active March 18, 2024 07:19
Xcode lldb debugging tips
Make sure Product->Scheme->Edit Scheme->Run is using "Debug" mode
(lldb) p NSPointFromString(@"{10.0, 20.0}");
error: 'NSPointFromString' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (NSPoint)NSPointFromString(@"{10.0, 20.0}”);
(NSPoint) $0 = (x = 10, y = 20)
(lldb) e @import UIKit
(lldb) po self.view.bounds
To be able to import non-native framework files in Xctest,
go to test target configuration -> build settings -> frame work search path,
add $(PROJECT_DIR) entry.
@thornpig
thornpig / synchronize_with_runloop_or_semaphore.m
Last active June 13, 2016 13:36
Synchronize asynchronous task with NSRunloop or diaptch_semaphore
//with semaphore
self.sem = disptach_semaphore_create(0);
[someAsyncTask start]; //someAsyncTask needs to call dispatch_semaphore_signal(self.sem) after the its work is done.
disptach_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
NSLog(@"task is done!");
//with NSRunloop
self.taskIsDone = NO;
[someAsyncTask start]; //someAsyncTask needs to set self.taskIsDone = YES after the work is done.
while (!self.taskIsDone)
@thornpig
thornpig / main_queue_thread_GCD.m
Created June 7, 2016 23:01
Main queue and main thread in GCD
//The main queue must be associated with the main thread.
//The main thread is not exclusively associated with the main queue.
//For example, when disptach_sync is used to dispatch a task from queue A to queue B,
//queue B will use the same thread queue A is using to execute the task.
//So, if a task is dispatched to a non-main queue from the main queue with dispatch_sync,
//the non-main queue will use the main thread to execute the task.
//Check if a task is running on the main thread,
[NSThread isMianThread];
@thornpig
thornpig / scrollViewJumpsWhenSettingContentIset.m
Created July 19, 2016 21:40
Setting contentInset of scrollView makes it jump
The cause of this problem is when the contentInset is set, contentOffset is also set to a value according to the new value of contentInset.
So restore contentOffset to its old value after setting contentInset solves the problem.
It seems the animation block is not needed in my app with iOS 9.0.
- (void)setLoadingScrollViewInsets:(UIScrollView *)scrollView
{
UIEdgeInsets loadingInset = scrollView.contentInset;
loadingInset.top += self.view.frame.size.height;
CGPoint contentOffset = scrollView.contentOffset;
@thornpig
thornpig / controlScrollSpeedWhenHideRefreshControl.m
Created July 20, 2016 20:23
Control the scroll speed when hiding refresh control in table view
//need double animation blocks
if (self.tableView.contentInset.top == 0)
{
UIEdgeInsets tableViewInset = self.tableView.contentInset;
tableViewInset.top = -1.*kTableHeaderHeight;
[UIView animateWithDuration: 0 animations: ^(void){} completion:^(BOOL finished) {
[UIView animateWithDuration: 0.5 animations:^{
//no need to set contentOffset, setting contentInset will change contentOffset accordingly.
self.tableView.contentInset = tableViewInset;
}];
@thornpig
thornpig / Lock scroll view scroll to horizontal or vertical direction
Last active October 4, 2016 19:45
Lock scroll view scroll to horizontal or vertical direction
scrollView.directionalLockEnabled still allows diagonal scrolling.
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.initialOffeset = scrollView.contentOffset;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//lock scroll direction
CGFloat xdis = scrollView.contentOffset.x - self.initialOffeset.x;
@thornpig
thornpig / BulletedParagraphs.swift
Created August 17, 2018 20:50
Create bulleted paragraphs
//copied from Ben Dodson's website.
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .UIContentSizeCategoryDidChange, object: nil)
updateUI()
}