IanMK2 Blog

가끔씩 xcode4를 사용하다보면 syntax관련 기능이 작동하지않는다.


해결법은 window->orgernizer->projects-> Derived Data

Posted by IanMK2
xcode로 static library를 제작하면 디바이스용과 시뮬레이터용으로 나뉘어 빌드가 된다.
귀찮으니까 통합하자
한곳에 모아놓고
커맨드로 libtool -static lib디바이스.a lib시뮬.a -o lib샬롸샬롸.a
 
Posted by IanMK2
제가 오늘 얘기할것은 UICustomTableView사용시 많은 분들이 "빼먹는"것에 대한 것입니다.


UICustomTableViewCell은 아시다시피 단조로운 셀을 벗어나게 할 수 있는 소중하고 멋진 녀석이죠!

그런데 많은 분들이 커스템 셀의 경우 "큰" 실수를 하시는것을 많이 보았습니다.

일단 그 실수가 뭐인가 하기 전에 이 녀석을 한번 보죠!

dequeueReusableCellWithIdentifier


"어디서 많이봤는데.." 혹은, "앗 이 이녀석은.." 등 경험에 따라 눈에 익으신분도 있고 안 그러신분도 계실 것 입니다.

어디서봤을까요?

// Customize the appearance of table view cells.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *CellIdentifier = @"Cell";

    

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    }

    

    // Configure the cell...

    

    return cell;

}



바로 셀을 리턴하는 함수에서 볼 수 있습니다.
용도는 뭘까요??

아시겠지만 테이블뷰는 몇개의 데이터만 뿌릴 수 도, 수 백개의  리스트를 출력하기도 합니다.
그런데 과연 출력할 데이터가 수백개일때 셀도 수백개를 메모리에 할당하는 것일까요?

답은 당연히 "아닙니다"

static NSString *CellIdentifier = @"Cell";

 
여기서 @"Cell"이 바로 키(key) 입니다.
셀에서 하나, 혹은 몇개만 할당 후 

[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

이 코드 한줄로 할당한 셀(cell)을 찾아(deque) 재활용(reuse)하는겁니다


이제 이 함수가 이해 가시나요?


모르셨던분들은 메모리가 크지않는 아이폰에서 이 함수의 존재가 달리 보이실겁니다.



이제 제가 이야기하고자 하는 것의 본론으로 들어가보죠.


많은 분들이(심지어 몇몇 기본서에서도) 커스템셀의 사용법을 알려줄 때(xib생성방식으로 할 때)


      CustomTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellName];

if (cell == nil) {
NSArray* nib= [[NSBundle mainBundleloadNibNamed:cellName owner:self options:nil];

    cell = [nib objectAtIndex:0];        

}


이렇게만 설명하고 끝이납니다.


자 우리는 이때 의심을 한번 가져봐야 합니다. 과연 위의 코드로 셀을 생성할 때 저 

dequeueReusableCellWithIdentifier

로 리턴된값이 항상 nil일 수도 있지않을까 라고 말이죠.

근거는 간단합니다.

커스텀이 아닐때와 비교해보면 말이죠.




cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 


NSArray* nib= [[NSBundle mainBundleloadNibNamed:cellName owner:self options:nil];

cell = [nib objectAtIndex:0];        


자 이제 의심이 가기 시작하시나요?


눈치채셨겠지만 기본 셀은 reuseIdentifier라는 인자로 구분자를 넘겨줌니다.

하지만 커스템셀생성시엔 전혀 그런 과정이 없죠.

따라서 tableview에는 셀이 어떠한 Identifier로 큐잉이 되지 않는거죠.


자. 그렇다면 해결법은 무엇일까요??

간단합니다. 저 identifier를 적어주면 되는것이지요.





저것을 적어주지않고 그냥 해서 스크롤 내릴때마다 메모리에 셀이 계속해서 올라가게 되기 때문이죠.

모두들 CustomTableViewCell사용시 주의하세요~!
Posted by IanMK2

끝까지위로 뒤집는 컬 효과는 UIViewAnimationTransitionCurlUp
또는 UIModalTransitionStylePartialCurl 등으로 효과를 낼 수 있다. 
하지만 원하는것은 절반만 뒤집어 아래에 숨겨진 버튼을 사용하는것.
구글에게 물었더니 다음과같이 따끈따근한 예제가!
 
CATransition *animation = [CATransition animation];

[animation setDelegate:self];

[animation setDuration:0.35];

[animation setTimingFunction:UIViewAnimationCurveEaseInOut];

if (!curled){

animation.type = @"pageCurl";

animation.fillMode = kCAFillModeForwards;

animation.endProgress = 0.58;

    } else {

animation.type = @"pageUnCurl";

        animation.fillMode = kCAFillModeBackwards;

animation.startProgress = 0.42;

}

[animation setRemovedOnCompletion:NO];

[[logo.view layer] addAnimation:animation forKey:@"pageCurlAnimation"];

if (!curled) {

logo.view.alpha = 0;

} else {

logo.view.alpha = 1;

}

curled = !curled;

Posted by IanMK2

Client가 adhoc버전의 파일을 원해 보냈는데 아무리 해도 설치가 안된단다.
내컴에서도 해봤는데 어랍쇼 이게왜 안되는거지..
그래서 구글신에게 물어보았더니 아래와같이 재밌게 해결법을 제시하셨다.


Ad hoc distribution of iPhone, and now iPad, applications can feel like a circus sideshow.  Developers come clambering out of the Provisioning Portal like its an undersized automobile to jump through flaming code signing hoops.  Generate a certificate, create an application id, add devices, create a provision, install them all and try not to get burned.  If you fail to do one step, or perform a step incorrectly, the application build results will usually guide you to the solution.  But what about when you do everything by the book and you still get an error?

The majority of my distribution issues usually sprout up when Apple releases a new version of the iPhone SDK.  This time it happened to be installing iPhone SDK 4.  After upgrading I needed to generate some Ad Hoc distributions.  Since these apps are only supposed to be targeted for iPhone devices, the "Base SDK" gets configured for "iPhone Device 4.0" and the "Targeted Device Family" is set to "iPhone". The only other parameter that needed changing was the "iPhone OS Deployment Target".  This app was not quite ready for "4.0" so I switched the value to "iPhone OS 3.1.3".

I configured three apps using the described values in exactly the same fashion.  The Ad Hoc distributions were generated and then zipped off to be installed.  To my dismay I received an email saying that one of the apps was incapable of being installed.  When the app is dragged into iTunes, nothing happens.  Successive attempts to drag the app into iTunes prompts this warning:

A provisioning profile named embedded.mobileprovision already exists on this computer.  Do you want to replace it?

Click the "Yes" button.  Nothing happens.  Click the "No" button.  Nothing happens.  At this point, I have no idea if I want to replace it.  I just want the app to sync with iTunes.  Time and time again I verify that all provisions are installed and configured properly.  Of course, none of which are named embedded.mobileprovision.  Search Google for embedded.mobileprovision and see what turns up.  Maybe a Twitter feed from a confused and frustrated developer.

There may be a multitude of reasons why this warning would appear when attempting an Ad Hoc installation but let me share with you the reason I was experiencing this issue.  Contrary to the message, the problem had nothing to do with an existing embedded.mobileprovision profile.  Some secret sleuthing lead me to believe that the issue originated when I choose a different "iPhone OS Deployment Target" in the project settings.  While I cannot prove this, I can at least show you some things to check manually before iAnarchy.

Every application has an Info.plist file that is created out of the box.  Find it in your application "Resources" group and it may look something like this:

 

Notice the dictionary entry "Application Requires iPhone Environment".  Notice the checkbox is clearly checked.  That makes sense.  We are developing an application using the iPhone SDK so it is only necessary that the application requires an iPhone environment.  Now open that same file as "Plain Text" to view the XML document which makes up this info dictionary.  Ours looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSMainNibFile</key>
    <string>MainWindow</string>
    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleBlackOpaque</string>
</dict>
</plist>

The pertinent key/value pair we are looking for is "LSRequiresIPhoneOS" and an XML node indicating <true/>.  999 times out of 1000 I would guess this is normal.  But on my 1000th attempt to build an app I see different a value:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <string>YES</string>
    <key>NSMainNibFile</key>
    <string>MainWindow</string>
    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleBlackOpaque</string>
</dict>
</plist>

Notice how the value for <key>LSRequiresIPhoneOS</key> has been modified from a (bool)<true/> to a (string)<string>YES</string>.  How on earth this happened I cannot guarantee, but I can tell you that this is the reason "A provisioning profile named embedded.mobileprovision already exists on this computer".  If you take the time to manually replace the <string> node with a <true/> node you may be one step closer to a successful Ad Hoc distribution.

Posted by IanMK2