你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> (一)iOS開發--電子書模塊的設計制作

(一)iOS開發--電子書模塊的設計制作

編輯:IOS開發綜合

一.引言

從今天開始,在我的博客上開辟工作項目專欄,來總結記錄項目中的開發難點。第一篇記錄的是電子書模塊。

二.項目需求

一級界面:1.側滑菜單、2.書籍列表、3.上拉加載
二級界面:1.頭部書籍信息、2.書籍簡介、3.評價列表、4.評價功能(彈出評價界面)5.底部下載/閱讀功能
下載管理界面:1.下載的書籍信息、2.可側滑刪除
閱讀界面:1.電子書自適應大小(pdf文件)、2.翻頁 、3.記錄頁

三.總結(後台拿到的測試數據)

1.一級界面

0.0
菜單欄數據源vcTRteOjurDRttTTprXE19PA4LC0y7PQ8rfFtb221NOmtcS4uMDgz8I8YnIgLz4NCiq94r72t723qKO6PC9wPg0KPHByZSBjbGFzcz0="brush:java;"> NSMutableArray *allArrM = [NSMutableArray array]; NSMutableArray *childArrM = [NSMutableArray array]; for (BookMenuEntity *menu in result) { /** * pid為1的是父類 */ if ([menu.pid isEqual:@1]) { [allArrM addObject:menu]; } else [childArrM addObject:menu]; } /** *所有父類+排序 */ NSSortDescriptor *allSn = [[NSSortDescriptor alloc] initWithKey:@"sn" ascending:YES]; NSArray *newAllResult= [allArrM sortedArrayUsingDescriptors:@[allSn]]; /** *所有子類+排序 */ NSSortDescriptor *childSn = [[NSSortDescriptor alloc] initWithKey:@"sn" ascending:YES]; NSArray *childResult= [childArrM sortedArrayUsingDescriptors:@[childSn]]; /* 對應父類有幾個,這個可變數組救添加幾個數組 */ NSMutableArray *newChildResult = [NSMutableArray array]; for (int i =0; i

1.1
1.1.1
這裡寫圖片描述這裡寫圖片描述

因為要讓菜單欄彈出時書籍列表(UICollectionViewController)不可操作,所以加了背景遮罩。

backView = [[UIView alloc] initWithFrame:CGRectMake(0, HEADER, self.view.frame.size.width, self.view.frame.size.height)];
backView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
//加到標簽欄上
[self.tabBarController.view addSubview:backView];

 //單擊手勢,讓菜單收起   
tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureAction:)];
[tapGesture setNumberOfTapsRequired:1];
[backView addGestureRecognizer:tapGesture];

//為了讓菜單的透明度和背景區分,再加個小的背景    
view = [[UIView alloc] initWithFrame:CGRectMake(0, HEADER, self.view.frame.size.width/2.5, backView.frame.size.height)];
view.backgroundColor = [UIColor blackColor];
view.alpha = 0.7;
[view addSubview:self.menuTableView];
[self.tabBarController.view addSubview:view];

//沒有點擊菜單按鈕,默認為隱藏
backView.hidden = YES;
view.hidden = YES;

1.1.2
*遇到難點:(1)剛開始時,菜單能正常加到tabBarController.view上,後來push到二級界面後,就不能加到tabBarController.view上(presentd的可以)。

*解決方法:[self.tabBarController.view bringSubviewToFront:backView];
[self.tabBarController.view bringSubviewToFront:view];

1.1.3
菜單點擊需求。1??點到誰,誰就變紅(表示選中,父類也可以被選中並進行數據加載)2??選中以後,再點擊,不進行數據請求3??點擊一個父類,其它父類子菜單要全部收起
思路:用一個數組來記錄點擊選中狀態、以及展開閉合狀態

/**
 *  1展開,0收起
 */
- (void)loadMenuData {
    //用0代表收起,非0(不一定是1)代表展開,默認都是收起的
    for (int i = 0; i < self.allMenuArrM.count; i++) {
        [self.isExpland addObject:@0];
    }
    if (self.isExpland.count != 0) {
        [self.menuTableView reloadData];
    }
}
#pragma mark 加載菜單欄父類是否被選中的數據
/**
 *  默認第一個父類被選中,1被選中,0沒有
 */
- (void)parentChooseAction{
    for (int j=0; j

1.1.4
*遇到難點:(4)因為菜單涉及到很多數據,然後進行多次表格刷新。所以容易出現數組越界
*解決方法:數組為空的時候可能進行了reloadTableView,進行判空操作。盡量減掉重復的reloadTabelView(一開始有四處,後來減到兩處)

1.2
1.2.1
這裡寫圖片描述
*遇到難點:(1)布局collectionViewCell
*解決方法:其它都好弄,但在解決每個cell的間距的時候一定要記住一個屬性:minimumInteritemSpacing,不設置它,cell的間距調不了。記得代理UICollectionViewDelegateFlowLayout。

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
self.collectionView.collectionViewLayout = flowLayout;
flowLayout.minimumInteritemSpacing = 12.5;
[self.collectionView registerClass:[EBookCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
/*
設置cell的大小
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    return CGSizeMake(90, 202);
}
/*
cell的布局上左下右的屏幕間距
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(10, 12.5, 10,12.5);
}

1.2.2
*遇到難點:(2)書籍介紹需求默認可以顯示三行,但是字不夠的時候,如何讓字頂住左上角
*解決方法:
_introduceLabel.lineBreakMode = NSLineBreakByWordWrapping;//一定要設置這個屬性
cell.introduceLabel.text = [NSString stringWithFormat:@"%@\n\n",@"哈哈哈"];

1.2.3
*遇到難點:(3)字體天空藍
*解決方法:推薦一個好用的第三方顏色器(都調好了)http://download.csdn.net/detail/xj_love/9542251

_introduceLabel.textColor = [UIColor colorWithRed:0/255.0f green:178/255.0f blue:238/255.0f alpha:1.0];

2.二級界面

2.1
2.1.1
二級默認界面,沒有難點!
//注意書籍名標簽字的位置1.2.2的難點(2)一樣

2.1.2
評價列表!
公司用autoLayout進行布局。
*遇到難點:(1)評價內容Label高度自適應(2)cell高度自適應
*解決方法:1??獲取文字高度:

/*.h文件*/
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *reviewLabelHeight;
/*.m文件*/
- (void)layoutSubviews{
CGSize size = [_review_content.text boundingRectWithSize:CGSizeMake(300, 1000) options: NSStringDrawingTruncatesLastVisibleLine"NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13.0]} context:nil].size;
_reviewLabelHeight.constant = size.height;
}

2.2
2.2.1
點擊右上角評價按鈕
同樣的,弄個背景View加到self.view上。添加單擊手勢。

2.2.2
*遇到難點:(1)在textView上加一個類似placheholder的提示語。(textfile的有這個屬性,textView沒有)
*解決方法:在textview上加一個Label,然後在textView的代理方法中 #pragma mark textView代理方法
- (void)textViewDidBeginEditing:(UITextView *)textView {
self.promptLabel.hidden = YES;


2.2.3
*遇到難點:(2)怎樣判斷textView沒有輸入內容已經輸入的為空格。
*解決方法:
/*
//進行一個過濾,找出空格
NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *trimedString = [self.textView.text stringByTrimmingCharactersInSet:set];
*/
if (self.textView.text.length !=0&&trimedString.length !=0) {
}

3.下載管理界面

3.1
3.1.1
管理
下載管理界面(電子書)

*遇到難點:書名高度自適應,cell高度自適應
*解決方法:參考2.1.2

3.1.2
側滑刪除下載書籍

實現側滑刪除:

/**
 *  1.開啟允許編輯
 *  2.提交編輯
 *  3.把英文轉換成中文
 */
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        DownBookInfoEntity *listModel = self.downloadArrM[indexPath.row];
        [DAO_DownBook deleteBookInfoWithBookID:(NSString *)listModel.ID];
        NSString *bookUrl = [NSString stringWithFormat:@"%@%@",Host1,listModel.file];
        NSString *path = [MANAGER_FILE.CSDownloadPath stringByAppendingPathComponent:[NSString stringWithFormat:@"file/%@", [bookUrl lastPathComponent]]];
        /*從數據庫刪除*/
        [MANAGER_FILE deleteFolderPath:path];
        [self.downloadrrM removeObjectAtIndex:indexPath.row];
        //數組是[indexPath]的數組
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"刪除";
}

4.電子書閱讀

用我的方法,就不用管電子書的寬高,它會自適應。

其實電視書是把一個UIScrollView加到控制器上,然後把pdfView加到UIScrollView上。

/*獲取pdf文件*/
pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);
/*獲取文件總頁數*/
pageCount = (int)CGPDFDocumentGetNumberOfPages(pdf);
-(void)drawInContext:(CGContextRef)context atPageNo:(int)page_no{
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(context,self.bounds);
    CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    if (self.pageNO == 0) {
        self.pageNO = 1;
    }
    CGPDFPageRef page = CGPDFDocumentGetPage(self.pdfDocument, self.pageNO);
    CGContextSaveGState(context);
    CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, self.bounds, 0, true);
    CGContextConcatCTM(context, pdfTransform);
    CGContextDrawPDFPage(context, page);
    CGContextRestoreGState(context);

}

四.其它總結

1.文件下載

ASIHttpRequest很好用的網絡請求第三方。可以get,post請求,支持斷點下載。

/**
 *  下載文件
 *  @param urlStr 文件路徑
 *  @param block  回調
 */
- (void)downloadFile:(NSString *)urlStr withType:(int)type finishCallbackBlock:(void (^)(BOOL result))block {
- 
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:urlStr]];

    NSString *filename = [urlStr lastPathComponent];
//下載後存儲文件名
    NSString *savePath = [MANAGER_FILE.CSDownloadPath stringByAppendingPathComponent:[NSString stringWithFormat:@"file/%@", filename]];
    NSString *tempPath = [MANAGER_FILE.CSDownloadPath stringByAppendingPathComponent:[NSString stringWithFormat:@"temp/%@", filename]];

    [request setDownloadDestinationPath:savePath];
    [request setTemporaryFileDownloadPath:tempPath];
    [request setShouldContinueWhenAppEntersBackground:YES];
    [request setDownloadProgressDelegate:self];
    [MANAGER_SHOW showProgressWithInfo:@"下載中..."];
    [request setCompletionBlock:^{
        [MANAGER_SHOW setProgress:1.0];
        if ([MANAGER_FILE fileExists:savePath]) {  
            block(YES);
        }else {
            block(NO);
        }
    }];
    [request setFailedBlock:^{
        [MANAGER_SHOW setProgress:1.0];
        block(NO);
    }];
    [request startAsynchronous];
}

2.get請求

/*
typedef void (^GetBackBlock)(id obj);
typedef void (^GetFailBlock)(NSError *error);
*/
- (void)doGetJson:(NSString *)urlstr withCompletionBlock:(GetBackBlock)completionBlock withFailBlock:(GetFailBlock)failBlock {
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:urlstr]];
    [request startAsynchronous];
    __block ASIHTTPRequest *_request = request;
    [request setCompletionBlock:^{
        switch ([_request responseStatusCode]) {//HTTP狀態碼
            case 404://Not Found 無法找到指定位置的資源
            case 500://Internal Server Error 服務器遇到了意料不到的情況
                failBlock([_request error]);
                break;
            case 200://OK 一切正常
                completionBlock([_request responseData]);
                [MANAGER_SHOW dismiss];
                break;
            default:
                failBlock([_request error]);
                break;
        }
    }];
    [request setFailedBlock:^{
        failBlock([_request error]);
        [MANAGER_SHOW dismiss];
    }]
}

3.post傳輸

- (void)doPostJson:(PostModel *)model withSuccessBlock:(GetBackBlock)successBlock withFailBlock:(GetFailBlock)failBlock {
    ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:[model.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];

    [request setRequestMethod:@"POST"];
    for (NSString *key in [model.params allKeys]) {
        [request setPostValue:[model.params objectForKey:key] forKey:key];
    }
    [request buildPostBody];
    [request startAsynchronous];

    __block ASIFormDataRequest *_request = request;
    [request setCompletionBlock:^{
        [MANAGER_SHOW dismiss];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            BLOCK_SUCCESS([_request responseData]);
        });
    }];
    [request setFailedBlock:^{
        [MANAGER_SHOW dismiss];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            BLOCK_FAILURE([_request error]);
        });
    }];
}
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved