Thursday, February 16, 2012

Keyboard notification bug on iOS 5

When the soft keyboard appears, we need to re-arrange the UI controls. I move the control up a little bit in keyboardWillShow handler:

frame.origin.y -= CONSTANT;

control.frame = frame;

But there is an annoying bug (or behavior) about non-English language keyboard on iOS 5. If you are using English keyboard, you will receive keyboardWillShow notification once. It is good. But if you are using some language keyboard like Chinese, you will receive the same notification TWICE! That means the above code will move the control up twice.

Some non-English language keyboard has an additional line at the top, used to choose words. Sounds like that additional line causes this problem.

The solution is simple. Just use hard-coded positions. And the additional line on some non-English language keyboards may cover parts of your UI on iOS 5. You have to leave enough space for keyboards. If your textField requires English characters only, you can force the keyboard to show English:

textField.keyboardType = UIKeyboardTypeASCIICapable;

Tuesday, December 27, 2011

Scroll NSScrollView to Top

AppKit is old and is not as convenient as UIKit. But we have to use it on Mac app development.

"Scroll a scrollview to top" sounds easy, but actually it isn't. If you assign a documentView to a NSScrollView, you will see it scrolls to the bottom. (Very stupid!) The doc did not mention how to scroll to top. I found a way to control the vertical scroller. I can set the scroller to top, but the scrollView is still at bottom!

This post (http://stackoverflow.com/questions/4506391/nsscrollview-jumping-to-bottom-on-scroll) inspired me. I got the solution (of cause, I post my answer on stackoverflow too):

// Scroll the vertical scroller to top

if ([_scrollView hasVerticalScroller]) {

_scrollView.verticalScroller.floatValue = 0;

}

// Scroll the contentView to top

[_scrollView.contentView scrollToPoint:NSMakePoint(0, ((NSView*)_scrollView.documentView).frame.size.height - _scrollView.contentSize.height)];

Friday, December 09, 2011

Wrong info from proc_pidinfo

proc_pidinfo is a very useful function to get a Mac OS X process's info such as the size of resident memory, consumed CPU time.

However, sometimes, the returned info is not correct. For example, a little process's resident memory becomes 4GB. Apple does not provide any document about this function, and I did not see useful comments in the header files.

I am lucky enough to see code snippet in the Apple open source file: http://www.opensource.apple.com/source/lsof/lsof-28/lsof/dialects/darwin/libproc/dproc.c. When we call proc_pidinfo, we must check the returned value. If the returned value is not identical to the size of output data, the output data is wrong.

      nb = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &ti, sizeof(ti));
            if (nb <= 0) {
                if (errno == ESRCH)
                    continue;
                if (!Fwarn) {
                    (void) fprintf(stderr, "%s: PID %d information error: %s\n",
                        Pn, pid, strerror(errno));
                }
                continue;
            } else if (nb < sizeof(ti)) {
                (void) fprintf(stderr,
                    "%s: PID %d: proc_pidinfo(PROC_PIDTASKALLINFO);\n",
                    Pn, pid);
                (void) fprintf(stderr,
                    "      too few bytes; expected %ld, got %d\n",
                    sizeof(ti), nb);
                Exit(1);
            }
I checked the processes with correct info. They are all my processes (not system processes). Seems like my app runs in user mode and it does not have privileges to get info of system processes.

Tuesday, October 18, 2011

Let Several Apps Use the same Facebook App ID

If you want to let your user post something from your app onto Facebook, you need to register a Facebook app and call Facebook SDK to post messages. But if you have a free version and a paid version, you would like to share the same Facebook App ID.

Just follow Facebook tutorial to register Facebook App and config your apps. https://developers.facebook.com/docs/mobile/ios/build/

The only one thing I need to mention is you must leave 'iOS Bundle ID' empty.

From Facebook doc page:

iOS Bundle ID - (Optional) You may set this to match the bundle ID for your iOS app. If you add this setting then the bundle ID of your app will be checked before authorizing the user. The benefit of this setting for SSO is if the user has already authorized your app they will not be asked to authorize it when they access your app from a new device.

Sunday, October 09, 2011

Xcode 4 and Git

I am new to Git. I used Perforce (P4) before, so I thought it is easy to use Git. Actually I was wrong. Git is not complex, but it has different concept.

In P4, we just check out and check in files. In Git, checking in has a new name Commit. When I committed my first change, I was surprised to see it does not appear in the server. Actually, Git did not really submit my code to the server. It was stored locally. I have to run this command in the command line:

git push origin master

So you must Push the local Commits to the server.

The problem is Xcode 4 can Pull, Commit, Compare, but does not provide Push functionality. How stupid the designer is. You can modify but cannot submit! Actually Pull, Commit and Compare are the only functionalities Xcode 4 provides. You cannot even revert!

Xcode 4 is free, but Apple should not make it suck.

Update on Nov 30, 2011:

SourceTree on Mac App Store is an excellent Git client. It is much better than GitX. And it is FREE!

Tuesday, October 04, 2011

Fixing the Problem of Cocos2D Game Disappearing in iPhone Simulator

I Created a new Cocos2D game. But it did not work well in iPhone simulator. It often disappeared in the simulator. I had to relaunch the simulator or relaunch Xcode. It was very boring. I didn't know why, because this project was still very simple.

I noticed there is a warning that Info.plist is included in the target. I did the following things:

1. Renamed Info.plist to ProjectName-Info.plist

2. Changed Info.plist to the same name in the target settings

3. Removed ProjectName-Info.plist from the target

The problem fixed!