iOS에서 label에 긴 한글을 넣을 경우 속도가 느려지는 현상

언젠가부터 iOS에서 label의 height을 Ti.UI.SIZE로 했을 경우
긴 한글을 넣으면 화면에 그려지기까지 속도가 느려지는 현상이 나타났는데
아직 원인을 모르겠네요.
이게 iOS 버전 탓인지 아니면 Ti SDK 탓인지… ㅠㅠ
(영어는 아무 문제 없습니다.)

혹시 이와 관련된 문제를 겪었거나 해결책을 아시는 분 있나요?
insturument로 일단 파악해봐야겠네요.

음. 그려질 때 느린것은 잘 모르겠고, 스크롤 할때 덜컥 거리기 때문에 디바이스 별로 글자를 그린 뒤 면적을 계산해서 고정높이로 주고 있습니다…

문서에도 size로 주면 덜컥(jerk?) 거린다고 하더군요.

1개의 좋아요

문제는 한글이 유난히 훨씬 더 느리다는 거죠. ^^

일단 다행히 이 문제는 안드로이드에서는 느려지는게 느껴지지 않네요.

높이 계산은 어떻게 하고 계신거에요? 예전에 iOS에서는 모듈 만들어서 NSString의 sizeWithFont를 썼었는데 … 따로 모듈 만드셨어요? 아니면 그냥 toImage?

무식하게 앱 로딩 타이밍에 그려보고 저장해뒀다가 계속 씁니다.

<Alloy>
  <!-- size 계산용. -->
  <View id="forCharLabelSize" class="forCharLabelSize">
    <!-- font13짜리 한글, 숫자, 영어, 공백, 특수문자, . -->
    <Label id="char_13_k" class="char_13" text="한"/>
    <Label id="char_13_n" class="char_13" text="4"/>
    <Label id="char_13_e0" class="char_13" text="E"/>
    <Label id="char_13_e1" class="char_13" text="e"/>
    <Label id="char_13_s0" class="char_13" text=" "/>
    <Label id="char_13_s1" class="char_13" text="!"/>
    <!-- font14짜리 한글, 숫자, 영어, 공백, 특수문자, . -->
    <Label id="char_14_k" class="char_14" text="한"/>
    <Label id="char_14_n" class="char_14" text="4"/>
    <Label id="char_14_e0" class="char_14" text="E"/>
    <Label id="char_14_e1" class="char_14" text="e"/>
    <Label id="char_14_s0" class="char_14" text=" "/>
    <Label id="char_14_s1" class="char_14" text="!"/>
    <!--  height-->
    <Label id="char_13_line1" class="char_13" text="w"/>
    <Label id="char_13_line2" class="char_13" text="ww\nww"/>
    <Label id="char_13_line3" class="char_13" text="w\nw\nw"/>
  </View>
</Alloy>

그리고 open이벤트에서 읽어서 전역 싱글톤 객체에 저장해둬요.

APP.H_F13 || (APP.H_F13 = {});
APP.H_F13['1'] = $.char_13_line1.size.height; //HEIGHT한줄.
APP.H_F13['2'] = $.char_13_line2.size.height; //HEIGHT한줄.
APP.H_F13['3'] = $.char_13_line3.size.height; //HEIGHT한줄.
//width는 한글,영소,영대,공백,!,. 별로.
APP.W_F13 || (APP.W_F13 = {});
APP.W_F13['k'] = $.char_13_k.size.width;
APP.W_F13['n'] = $.char_13_n.size.width;
APP.W_F13['e0'] = $.char_13_e0.size.width;
APP.W_F13['e1'] = $.char_13_e1.size.width;
APP.W_F13['s0'] = $.char_13_s0.size.width;
APP.W_F13['s1'] = $.char_13_s1.size.width;
//width는 한글,영소,영대,공백,!,. 별로.
APP.W_F14 || (APP.W_F14 = {});
APP.W_F14['k'] = $.char_14_k.size.width;
APP.W_F14['n'] = $.char_14_n.size.width;
APP.W_F14['e0'] = $.char_14_e0.size.width;
APP.W_F14['e1'] = $.char_14_e1.size.width;
APP.W_F14['s0'] = $.char_14_s0.size.width;
APP.W_F14['s1'] = $.char_14_s1.size.width;

무식하지만 가장 확실한 방법이죠…

이걸 계산하는 유틸리는 이렇게 씁니다.

/* 
* label의 최대 줄을 제한하하는 용도(newfeedList의 W_F13등의 값할당에 의존.
*
* calculateHeightOfLimitLine({
*   startWidth: startWidth, //option
*   lineWidth: (CTX.width() - (26*2)),
*   maxLine: 4, //TODO 짧게하면 제대로 안나옴. 길어도 현재는 그냥 세줄로 제약두니괜찮음.
*   fontSize: 13
*   text: text,
* })
*
* return {   maxHeight: maxHeight, lastCharIdx: lastCharIdx  }
**/
exports.calculateHeightOfLimitLine = function (params) {
  var APP = require("core");
  // APP.log("debug", "calculateHeightOfLimitLine", params);
  
  //required
  var text = params['text'] || ''
  , LINE1_WIDTH = params['lineWidth']
  , LINE2_WIDTH = params['lineWidth'] * 2
  , LIMIT_LINE_WIDTH = LINE1_WIDTH * params['maxLine']
  , W_FONT = 'W_F' + (params['fontSize'] || 13)
  , H_FONT = 'H_F' + (params['fontSize'] || 13);
  
  //option
  var curWidth = params['startWidth'] || 0;
  //한 글자식 확인.
  var lastCharIdx = 0;
  for(var max=text.length; lastCharIdx<max; ++lastCharIdx){
    if( curWidth >= LIMIT_LINE_WIDTH ) break;
    
    curWidth += APP[W_FONT][exports.getCharType(text.charCodeAt(lastCharIdx))];
    
  }      
  
  //curWidth에 맞는 높이는?
  var maxHeight = 0;
  if ( curWidth < LINE1_WIDTH ){
    maxHeight = APP[H_FONT]['1'];
  } else if( curWidth > LINE2_WIDTH ) {
    maxHeight = APP[H_FONT]['3'];
  } else {
    maxHeight = APP[H_FONT]['2'];
  }
  
  return {
    maxHeight: maxHeight,
    lastCharIdx: lastCharIdx
  }
}


//char_ASCII: text.charCodeAt(i)
exports.getCharType = function (char_ASCII){
  // APP.log("error", "char_ASCII",char_ASCII)
  // APP.W_F13['k'] = $.char_13_k.size.width;
  // APP.W_F13['n'] = $.char_13_n.size.width;
  // APP.W_F13['e1'] = $.char_13_e1.size.width;
  // APP.W_F13['s0'] = $.char_13_s0.size.width;
  // APP.W_F13['s1'] = $.char_13_s1.size.width;
  if((char_ASCII >= 12592) || (char_ASCII <= 12687)){
     //한글
     return 'k';
  }else if (char_ASCII == 32){
    //공백
    return 's0'
  }else if(char_ASCII >= 48 && char_ASCII <= 57 ){
    //숫자
    return 'n';
  }else if(char_ASCII>=65 && char_ASCII<=90){
    //영어(대문자)
    return 'e0';
  }else if(char_ASCII>=97 && char_ASCII<=122){
    //영어(소문자)
    return 'e1';
  }else if ((char_ASCII>=33 && char_ASCII<=47)
  || (char_ASCII>=58 && char_ASCII<=64)
  || (char_ASCII>=91 && char_ASCII<=96)
  || (char_ASCII>=123 && char_ASCII<=126)){
    //특수기호
    return 's1';
  }else{
    //기타는 그냥 한글과 같이.
    return 'k';
  }
}

ㅎㅎ 재밌죠… 완전히 딱 맞지는 않는데, 거의 맞습니다.

1개의 좋아요

대박!
거의 맞는다는 사실이 놀라워요!

페이스북은 모든 디바이스에 모든 글꼴 별로 다 계산해서 미리 레이아웃의 사이즈를 결정한다고 들었습니다.
페이스북의 발치에도 못 미치지만 결국 스크롤 성능 때문에 계산을 해야되더라구요…

우리 알림 리스트가 글자도 많아지고 이미지도 많아져서 버벅거리는데…이거좀 적용해 봐야 겠네요~

@jazzparty 안드로이드는 괜찮지 않아요?

안드로이드도 height가 Ti.UI.SIZE면서 listview에 아이템이 많으면 스크롤 할때 버벅버벅 거려요.