You can do this:
[[textView layoutManager] usedRectForTextContainer:[textView textContainer]].size
You can do this:
[[textView layoutManager] usedRectForTextContainer:[textView textContainer]].size
These equations are by Robert Penner, you can find a document here that explains this in much greater detail:
http://www.robertpenner.com/easing/
The correct linear tween function looks like this:
float linear_tween(float t, float start, float end) { if (t > 1.0f) return end; return t * end + (1.0f - t) * start; }
t is the time since the start of animation started and it has to be between 0 and 1, start and end are the values that you want to interpolate between them…
To understand this equation you can so something very simple, assume start is 1 and end is 20, then at timestep 0 you will have:
0 * end + (1 – 0) * start => start
At time step 1 which is the end of your animation you get:
1 * end + (1 – 1) * start => end
And all the values between these are going to be interpolated linearly.
Now quadratic ease in function is where the changes in interpolated value are smaller in the beginning and larger at the end, how can we achieve this? We can do it by faking the time steps, if you we could somehow make it so that the time steps would look smaller to the linear tween function at the start of the animation and larger at the end, then we would achieve this, that way, in the beginning, the time steps look smaller so the function will change the value by just a little bit but at the end, the time steps look larger so the function will change the value by a larger amount.
The way to do this is very easy, the fact that the time step number is clamped to between 0 and 1 will help us in this case and this is the solution:
float quadratic_easein(float t, float start, float end) { if (t > 1.0f) return end; return linear_tween(t * t, start, end); }
When we multiply the time step by itself the numbers that are less than one get smaller, for example if you are at the time step 1/10th of a second:
1/10 * 1/10 => 1/100
2/10 * 2/10 => 4/100 (3/100 change)
3/10 * 3/10 => 9/100 (5/100 change)
4/10 * 4/10 => 16/100 (7/100 change)
…
8/10 * 8/10 => 64/100
9/10 * 9/10 => 81/100 (17/100 change)
Now let’s look at quadratic_easeout:
float quadratic_easeout(float t, float start, float end) { if (t > 1.0f) return end; return linear_tween(2 * t - t * t, start, end); }
Deriving 2*t – t*t is very easy knowing the fact above; to do this we need to reverse what happens above so we can do something:
t = 1 – t;
Now 1/10 becomes 9/10 so when we do:
t = t * t
The numbers are going to change more at the beginning of the time step but the problem is that now we converted 1/10 to 9/10 and t*t will result in 81/100 and that’s the end of our time step and the animation will play backwards, to fix it we need to do:
t = 1 – t
One more time so then 81/100 becomes 19/100, now let’s simplify this:
1 – t => 1 – t * t => 1 – ((1 – t) * (1 – t)) => 1 – (1 – t – t + t * t) => 2 * t – t * t
I hope this helps
This was happening because I accidentally deleted “Bundle Display Name” from my info.plist…..
If you have to send notifications from secondary threads, then you might have noticed that your app crashes randomly and it’s unstable, the way to get around this is to have a method that sends the notification and use a second method to call that method using performSelectorOnMainThread like so:
- (void)doPostStatusNotification:(NSString *)message { [[NSNotificationCenter defaultCenter] postNotificationName:@"SOME_ID" object:self userInfo:[NSDictionary dictionaryWithObject:message forKey:@"message"]]; } - (void)postStatusNotification:(NSString *)message { [self performSelectorOnMainThread:@selector(doPostStatusNotification:) withObject:message waitUntilDone:NO]; }
And, never call the first method, always use the second one…
I used to use timers to update my table views, but you know that the timer runs in the same thread that you create it and it attaches to the same runloop so that’s not very nice and it’s silly to make a thread for it so naturally you might end up making a timer with longer time intervals and your table view will have delays.
There is a nicer way of handling this, you can use NSKeyValueObserving and all you have to do in is to import two headers on top of your model:
#import <Foundation/NSKeyValueCoding.h> #import <Foundation/NSKeyValueObserving.h>
Then, when you load your model items attach observers to each one, like so:
[directory addObserver:self forKeyPath:@"some-property-of-your-model-object-like-status" options:NSKeyValueObservingOptionNew context:nil];
You can add and observer to as many properties as you want.
Then implement the delegate method in your controller:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (![the-table-view needsDisplay]) [the-table-view setNeedsDisplay:YES]; }
If you add new rows or remove them, you will need to send a reloadData message to your table view.
That’s it, much simpler than caveman way of doing it and updates are almost instant…
This happened to me and everything was working, the table was linked up properly to it’s delegate and datasource but I discovered that I was calling reloadData too many times, so this problem could be caused by two things:
1 – If you call reloadData too many times, it messes up some internal thing and it stops responding.
2 – It has a mechanism in place that detects this issue and kind of stops responding.
Now, to try to fix this, you must know what reloadData does, it simply sets a flag in the table view:
[the-table-view setNeedsDisplay:YES];
And if you did any reading or research you know that this doesn’t guaranty a refresh – which leads me to believe the second point above might be true – of the view so to fix my issue I tried:
if (![the-table-view needsDisplay]) [the-table-view setNeedsDisplay:YES];
You must call reloadData only when you add new/or remove data to/from the dataset.
This seems to be working…
Recently, I was trying to store a very large integer value in a SQLite column, it didn’t matter wether I used INTEGER or UNSIGNED BIG INT, SQLite rounded it for me and I was left with an integer value that wasn’t even close to what I needed.
So one solution was to just use a VARCHAR or TEXT or event a BLOB and insert the number with quotes around it but guess what? SQLite did it again!!!
It turns out that SQLite tries to convert your values to ints to give you some benefits with sorting and comparing etc. – in case you didn’t know you really wanted an int rather than a BLOB – and that happens here in one of it’s functions:
/* ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string ** looks like a number, convert it into a number. If it does not ** look like a number, leave it alone. */ static void applyNumericAffinity(Mem *pRec){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ double rValue; i64 iValue; u8 enc = pRec->enc; if( (pRec->flags&MEM_Str)==0 ) return; if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; pRec->flags |= MEM_Int; }else{ pRec->r = rValue; pRec->flags |= MEM_Real; } } }
The solution to this issue is to prepend a 0 to your number and use a BLOB or TEXT type column and insert it like this: ’0THEVERYLARGENUMBER’
Don’t get me wrong, SQLite is a great library that I’ve been using, it’s very well tested and works great, it’s fast and thread safe, I specially like it’s licensee:
/* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** *************************************************************************
I hope this helps…
[string stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[string substringToIndex:1] uppercaseString]];
- (NSString *)escape:(NSObject *)value {
if (value == nil)
return nil;
NSString *escapedValue = nil;
if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSMutableString class]]) {
NSString *valueString = (NSString *) value;
char *theEscapedValue = sqlite3_mprintf("'%q'", [valueString UTF8String]);
escapedValue = [NSString stringWithUTF8String:(const char *)theEscapedValue];
sqlite3_free(theEscapedValue);
} else
escapedValue = [NSString stringWithFormat:@"%@", value];
return escapedValue;
}I don’t know why I can’t find anything about this online but here are some of the events that the application sends out through NSNotificationCenter:
UIApplicationDidFinishLaunchingNotification
UIApplicationDidBecomeActiveNotification
UIApplicationWillResignActiveNotification
UIApplicationDidReceiveMemoryWarningNotification
UIApplicationWillTerminateNotification
UIApplicationSignificantTimeChangeNotification
UIApplicationWillChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarOrientationNotification
UIApplicationStatusBarOrientationUserInfoKey
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarFrameNotification
UIApplicationStatusBarFrameUserInfoKey
Use them like:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someMethod) name:UIApplicationWillResignActiveNotification object:nil];
It’s obvious what they are but if you have a question post a comment…