Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
          制作 iPhone 電子書時,如果把大段文字放在 UITextView 或 UILabel 里顯示,是不能分頁的,閱讀時就像再看一大卷滾不到頭的紙帶,用戶體驗很差。下面這段代碼可以實現 UILabel 尺寸固定,

            制作 iPhone 電子書時,如果把大段文字放在 UITextView 或 UILabel 里顯示,是不能分頁的,閱讀時就像再看一大卷滾不到頭的紙帶,用戶體驗很差。下面這段代碼可以實現 UILabel 尺寸固定,根據文本內容和字體動態分頁顯示,電子書方面的應用應該非常有用。

          // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
          - (void)viewDidLoad {
              [super viewDidLoad];
              
              //
              totalPages = 0;
              currentPage = 0;
              
              //
              textLabel.numberOfLines = 0;
              
              //
              if (!text) {
                  // 從文件里加載文本串
                  [self loadString];
                  
                  // 計算文本串的大小尺寸
                  CGSize totalTextSize = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]
                                                   constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)
                                              lineBreakMode:UILineBreakModeWordWrap];

                  // 如果一頁就能顯示完,直接顯示所有文本串即可。
                  if (totalTextSize.height < textLabel.frame.size.height) {
                      textLabel.text = text;
                  }
                  else {
                      // 計算理想狀態下的頁面數量和每頁所顯示的字符數量,只是拿來作為參考值用而已!
                      NSUInteger textLength = [text length];
                      referTotalPages = (int)totalTextSize.height/(int)textLabel.frame.size.height+1;
                      referCharatersPerPage = textLength/referTotalPages;
                      
                      // 申請最終保存頁面NSRange信息的數組緩沖區
                      int maxPages = referTotalPages;
                      rangeOfPages = (NSRange *)malloc(referTotalPages*sizeof(NSRange));
                      memset(rangeOfPages, 0x0, referTotalPages*sizeof(NSRange));
                      
                      // 頁面索引
                      int page = 0;
                      
                      for (NSUInteger location = 0; location < textLength; ) {
                          // 先計算臨界點(尺寸剛剛超過UILabel尺寸時的文本串)
                          NSRange range = NSMakeRange(location, referCharatersPerPage);
                          
                          // reach end of text ?
                          NSString *pageText;
                          CGSize pageTextSize;
                          
                          while (range.location + range.length < textLength) {
                              pageText = [text substringWithRange:range];
                              
                              pageTextSize = [pageText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]
                                                  constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)
                                                      lineBreakMode:UILineBreakModeWordWrap];
                              
                              if (pageTextSize.height > textLabel.frame.size.height) {
                                  break;
                              }
                              else {
                                  range.length += referCharatersPerPage;
                              }
                          }
                          
                          if (range.location + range.length >= textLength) {
                              range.length = textLength - range.location;
                          }
                          
                          // 然后一個個縮短字符串的長度,當縮短后的字符串尺寸小于textLabel的尺寸時即為滿足
                          while (range.length > 0) {
                              pageText = [text substringWithRange:range];
                              
                              pageTextSize = [pageText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]
                                                  constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)
                                                      lineBreakMode:UILineBreakModeWordWrap];
                              
                              if (pageTextSize.height <= textLabel.frame.size.height) {
                                  range.length = [pageText length];
                                  break;
                              }
                              else {
                                  range.length -= 2;
                              }
                          }
                          
                          // 得到一個頁面的顯示范圍
                          if (page >= maxPages) {
                              maxPages += 10;
                              rangeOfPages = (NSRange *)realloc(rangeOfPages, maxPages*sizeof(NSRange));
                          }
                          rangeOfPages[page++] = range;
                          
                          // 更新游標
                          location += range.length;
                      }

                      // 獲取最終頁面數量
                      totalPages = page;
                      
                      // 更新UILabel內容
                      textLabel.text = [text substringWithRange:rangeOfPages[currentPage]];
                  }
              }
              
              // 顯示當前頁面進度信息,格式為:"8/100"
              pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];
          }


          ////////////////////////////////////////////////////////////////////////////////////////
          // 上一頁
          - (IBAction)actionPrevious:(id)sender {
              if (currentPage > 0) {
                  currentPage--;
                  
                  NSRange range = rangeOfPages[currentPage];
                  NSString *pageText = [text substringWithRange:range];
                  
                  textLabel.text = pageText;

                  //
                  pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];
              }
          }

          ////////////////////////////////////////////////////////////////////////////////////////
          // 下一頁
          - (IBAction)actionNext:(id)sender {
              if (currentPage < totalPages-1) {
                  currentPage++;
                  
                  NSRange range = rangeOfPages[currentPage];
                  NSString *pageText = [text substringWithRange:range];
                  
                  textLabel.text = pageText;
                  
                  //
                  pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];
              }
          }

          posted on 2010-09-13 10:01 seal 閱讀(213) 評論(0)  編輯  收藏 所屬分類: iPhone
          主站蜘蛛池模板: 大连市| 新兴县| 临城县| 江西省| 河曲县| 永川市| 邯郸市| 临安市| 甘洛县| 曲松县| 康马县| 麟游县| 盈江县| 九寨沟县| 峨山| 和硕县| 天柱县| 台山市| 崇义县| 新绛县| 水富县| 汶上县| 牙克石市| 和政县| 桐柏县| 涞水县| 织金县| 营口市| 巧家县| 柳林县| 成武县| 耿马| 额尔古纳市| 铜山县| 英山县| 思南县| 敦煌市| 和平区| 克东县| 晋江市| 佳木斯市|