Reader开发(二)增加PDF阅读功能

来源:互联网 发布:气场强大的女生知乎 编辑:程序博客网 时间:2024/06/09 18:04

最近任务很多很忙,所以更新博客的速度很慢。

大概上周就为Reader加了一个PDF阅读的功能,但是一直没时间写上来。昨晚找一下文件发现扩展了功能的Demo居然在文件目录下看不到任何文件,但是却显示有文件大小,而且删除的时候还显示已锁定,应该不是文件被隐藏了的问题。没有办法之下,今天下午又重新把该功能在原来未修改过的Demo上写了回来,又花了一些时间。文件备份太重要了。


PDF文件和RTF,TXT这些格式的文件不同,这种文件中显示出的是图像而不是单纯的文字(就我肤浅的看法来看),这样Text Kit这个强大的文字处理引擎似乎就派不上用场了,不过可以使用官方给出的CGPDFDocumentRef和CGPDFPageRef类以及UIView的drawRect:方法来创建PDF文件和呈现PDF视图。

跟着之前Reader开发的思路,由于PDF的阅读视图是draw出来的,而RTF和TXT的阅读视图是直接使用AttributedString的,两者思路完全不同,如果将其阅读视图塞进一个ViewController中似乎会显得很乱,所以我新建了一个PDFViewController和一个PDFView类来专门管理PDF文件的阅读。

首先是在BookList表格中如果选中了PDF文件,那么跳转的目的视图控制器不是之前的ReadingViewController,而是新的PDFViewController,代码如下:

[cpp] view plain copy
  1. else if (indexPath.section == 2) { // pdf  
  2.         name = sPdfArray_[indexPath.row];  
  3.         PDFViewController *pdfVC = [[PDFViewController alloc] initWithPDFName:name];  
  4.         [self.navigationController pushViewController:pdfVC animated:YES];  
  5.         return;  
  6.     }  
在这里使用导航控制器push了一个PDFViewController进栈,而不是present视图控制器了。这样可以很方便地直接使用UINavigationItem的title来显示当前的阅读进度。


首先给出PDFViewController的接口部分,了解一下PDFViewController的成员结构:

[cpp] view plain copy
  1. #import <UIKit/UIKit.h>  
  2. #import "PDFView.h"  
  3.   
  4. @interface PDFViewController : UIViewController  
  5. @property (strong, nonatomic) PDFView *curView;  // 当前PDF页面视图  
  6. @property (strong, nonatomic) PDFView *addView;  // 新的PDF页面视图  
  7. @property (strong, nonatomic) PDFView *backView; // 用于制造翻页效果的视图  
  8. @property (strong, nonatomic) UIScrollView *scrollView; // 滚动视图,用于显示完整的PDF页面  
  9. @property (retain, nonatomic) CAGradientLayer *shadow;  // 用于制造阴影效果的Layer  
  10. @property (retain, nonatomic) CAGradientLayer *margin;  // 用于制造页边效果的Layer  
  11. -(id)initWithPDFName:(NSString *)name; // 通过PDF文件名初始化  
  12. @end  
以及匿名接口部分,里面包括一些私有的成员:
[cpp] view plain copy
  1. @interface PDFViewController ()  
  2. {  
  3.     BOOL next_;     // 是否翻向下一页  
  4.     BOOL enlarged_; // pdf视图是否被放大  
  5.     NSUInteger currentPage_; // 当前页号  
  6.     NSUInteger totalPages_;  // 总页数  
  7.     CGFloat startX_;    // 翻页手势起点的x值  
  8.     CGFloat curoffset_; // 翻页手势的位移值  
  9.     CGFloat minoffset_; // 翻页手势有效的最小位移值  
  10.     CGRect pdfRect_; // 完整的PDF页面的框架矩形  
  11.     CGRect fitRect_; // 适配后的PDF页面的框架矩形  
  12.     CGPDFDocumentRef pdfRef_;  // pdf文件  
  13.     CGPDFPageRef     pdfPage_; // pdf页面  
  14. }  
  15. @property (strong, nonatomic) UITapGestureRecognizer *doubleTap_; // 双击手势,用于查看完整的PDF页面  
  16. @property (strong, nonatomic) UIView *viewForPDF; // self.view中用于放置pdf阅读视图的子视图  
  17. @end  


来看看PDFViewController的初始化方法:

[cpp] view plain copy
  1. #pragma mark -  
  2. #pragma mark Initialize  
  3.   
  4. /* 通过PDF文件名初始化 */  
  5. -(id)initWithPDFName:(NSString *)name {  
  6.     self = [super init];  
  7.     if (self) {  
  8.         /* 根据pdf文件路径初始化pdf阅读视图 */  
  9.         NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:name]; // 获取PDF文件名的完整路径  
  10.         NSLog(@"filePath = %@", filePath); // 例如:filePath = /Users/one/Library/Application Support/iPhone Simulator/7.0/Applications/5815AD09-13F2-4C77-9CAE-ADD399E85A5E/PDFReader_i7_Demo.app/CGPDFDocument.pdf  
  11.         pdfRef_ = [self createPDFFromExistFile:filePath]; // 创建pdf文件对象  
  12.         pdfPage_ = CGPDFDocumentGetPage(pdfRef_, 1); // 创建pdf首页页面  
  13.         currentPage_ = 1; // 页号,从1开始  
  14.     }  
  15.     return self;  
  16. }  
  17.   
  18. /* 根据文件路径创建pdf文件 */  
  19. - (CGPDFDocumentRef)createPDFFromExistFile:(NSString *)aFilePath {  
  20.     CFStringRef path;  
  21.     CFURLRef url;  
  22.     CGPDFDocumentRef document;  
  23.       
  24.     path = CFStringCreateWithCString(NULL, [aFilePath UTF8String], kCFStringEncodingUTF8);  
  25.     url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);  
  26.     CFRelease(path);  
  27.       
  28.     document = CGPDFDocumentCreateWithURL(url);  
  29.     CFRelease(url);  
  30.       
  31.     totalPages_ = CGPDFDocumentGetNumberOfPages(document); // 设置PDF文件总页数  
  32.     NSLog(@"totalPages = %d", totalPages_);  
  33.     if (totalPages_ == 0) { // 创建出错处理  
  34.         NSLog(@"Create Error");  
  35.         return NULL;  
  36.     }  
  37.     return document;  
  38. }  
其中initWithPDFName:方法通过createPDFFromeExistFile:方法初始化了CGPDFDocumentRef类的对象。PDF文件对象的创建基本完成。


由于在阅读PDF阅读时要通过手势的移动来实现翻页,所以这里我沿用了之前的Touches in view的思路和框架,在PDFViewController的self.view中动态添加PDF阅读视图来实现阅读功能,那么就涉及到了PDFView类的使用,先看看初始化方法:

[cpp] view plain copy
  1. /* 初始化PDFView对象 */  
  2. - (id)initWithPDFRef:(CGPDFDocumentRef)pdfr {  
  3.     pdfRef = pdfr;  
  4.     pdfPage = CGPDFDocumentGetPage(pdfRef, 1); // 创建pdf首页页面  
  5.     self.pageIndex = 1; // 要展示的页面号,从1开始  
  6.     CGRect mediaRect = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);  
  7.     self = [super initWithFrame:mediaRect];  
  8.     return self;  
  9. }  
PDFView负责呈现PDF文件中的内容,PDFViewController负责控制PDFView的显示和布局。

注意PDFView是UIView类的子类,所以该类自带了一个drawRect:方法,要描绘出PDF的阅读内容,就必须要实现该方法:

[cpp] view plain copy
  1. /* drawRect:方法,每个UIView的自带方法 */  
  2. - (void)drawRect:(CGRect)rect {  
  3.     CGContextRef context = UIGraphicsGetCurrentContext(); // 获取当前的绘图上下文  
  4.     [[UIColor whiteColor] set];  
  5.     CGContextFillRect(context, rect);  
  6.     CGContextGetCTM(context);  
  7.     CGContextScaleCTM(context, 1, -1);  
  8.     CGContextTranslateCTM(context, 0, -rect.size.height);  
  9.     pdfPage = CGPDFDocumentGetPage(pdfRef, self.pageIndex);  
  10.     CGRect mediaRect = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);  
  11.     CGContextScaleCTM(context, rect.size.width / mediaRect.size.width, rect.size.height / mediaRect.size.height);  
  12.     CGContextTranslateCTM(context, -mediaRect.origin.x, -mediaRect.origin.y);  
  13.     CGContextDrawPDFPage(context, pdfPage); // 绘制当前页面  
  14. }  

另外在翻页时PDFView的内容必须作出更新,可以使用setNeedsDisplay方法来实现,而该方法必须被PDFViewController调用,所以可以将其写成一个接口供其它类使用:
[cpp] view plain copy
  1. /* 更新视图,例如翻页的时候需要更新 */  
  2. - (void)reloadView {  
  3.     [self setNeedsDisplay];  
  4. }  
接口部分:
[cpp] view plain copy
  1. @interface PDFView : UIView  
  2. {  
  3.     CGPDFDocumentRef pdfRef; // pdf文件  
  4.     CGPDFPageRef pdfPage;    // pdf页面  
  5. }  
  6. @property (assign, nonatomic) NSUInteger pageIndex; // 页面号  
  7. - (id)initWithPDFRef:(CGPDFDocumentRef)pdfr;  
  8. - (void)reloadView;  
  9. @end  
完成PDFView的任务后,我们回到PDFViewController上来,首先当然是viewDidLoad:方法了:
[cpp] view plain copy
  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.       
  4.     /* 初始化参数 */  
  5.     minoffset_ = self.view.frame.size.width / 5.;  
  6.     enlarged_ = NO; // 初始的PDF视图的放大状态为NO  
  7.       
  8.       
  9.     /* 初始化视图 */  
  10.     self.navigationItem.title = [NSString stringWithFormat:@"%d / %d", currentPage_, totalPages_];  
  11.     curView  = [[PDFView alloc] initWithPDFRef:pdfRef_];  
  12.     addView  = [[PDFView alloc] initWithPDFRef:pdfRef_];  
  13.     backView = [[PDFView alloc] initWithPDFRef:pdfRef_];  
  14.     backView.pageIndex = 0;  
  15.     scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];  
  16.     viewForPDF = [[UIView alloc] initWithFrame:CGRectMake(0., 60., self.view.frame.size.width, self.view.frame.size.height - 60.0)];  
  17.       
  18.       
  19.     /* 设置PDF阅读视图的页面布局 */  
  20.     CGFloat w = curView.frame.size.width;  
  21.     CGFloat h = curView.frame.size.height;  
  22.     pdfRect_  = curView.frame;  
  23.     CGFloat scale = h / w; // PDF原视图高度和宽度的比例  
  24.     NSLog(@"w = %f", w);  
  25.     NSLog(@"h = %f", h);  
  26.     CGFloat href = self.view.frame.size.width * scale; // 经过页面适配后的高度  
  27.     CGFloat yref = (self.view.frame.size.height - 60.0 - href) / 2.; // 经过页面适配后的原点y值  
  28.     NSLog(@"href = %f", href);  
  29.     NSLog(@"yref = %f", yref);  
  30.     curView.frame = CGRectMake(0., yref, self.view.frame.size.width, href); // 设置适配后PDF视图的位置和大小  
  31.     fitRect_ = curView.frame; // 保存适配后的框架矩形  
  32.     [self.view addSubview:viewForPDF];  
  33.     [viewForPDF addSubview:curView]; // 添加页面适配后的PDF视图  
  34.       
  35.       
  36.     /* 为视图添加双击手势 */  
  37.     doubleTap_ = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(enlargePDFPage:)];  
  38.     doubleTap_.numberOfTapsRequired = 2;  
  39.     [self.view addGestureRecognizer:doubleTap_];  
  40. }  



在这里说一下设置PDF阅读视图的页面布局这一段吧,由于PDFView的drawRect:方法没有draw出最适合页面的显示,所以看到如下显示:



也就是在没有UIScrollView来呈现PDFView的情况下,我们只能看到PDF页面的部分视图(放大后的),由于我对CGContextDraw这些方法真的一点都不熟悉,所以只能通过设置PDFView的frame来解决该问题了。

首先获取初始的PDFView的视图尺寸并将其保存起来:

[cpp] view plain copy
  1. CGFloat w = curView.frame.size.width;  
  2. CGFloat h = curView.frame.size.height;  
  3. pdfRect_  = curView.frame;  
  4. 2013-09-13 18:02:34.210 Reader_i7_Demo[2257:a0b] w = 612.000000  
  5. 2013-09-13 18:02:34.211 Reader_i7_Demo[2257:a0b] h = 792.000000  

然后通过宽高比例进行适配并将其保存起来:

[cpp] view plain copy
  1. CGFloat scale = h / w; // PDF原视图高度和宽度的比例  
  2. NSLog(@"w = %f", w);  
  3. NSLog(@"h = %f", h);  
  4. CGFloat href = 320. * scale; // 经过页面适配后的高度  
  5. CGFloat yref = (510. - href) / 2.; // 经过页面适配后的原点y值  
  6. NSLog(@"href = %f", href);  
  7. NSLog(@"yref = %f", yref);  
  8. curView.frame = CGRectMake(0., yref, self.view.frame.size.width, href); // 设置适配后PDF视图的位置和大小  
  9. fitRect_ = curView.frame; // 保存适配后的框架矩形  

来看看适配后的页面视图:


现在另一个问题来了,文字太小,看不到完整的pdf内容(以iPhone的尺寸来看),这个时候可以在视图中添加一个双击手势来显示完整的pdf内容:

[cpp] view plain copy
  1. /* 为视图添加双击手势 */  
  2. doubleTap_ = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(enlargePDFPage:)];  
  3. doubleTap_.numberOfTapsRequired = 2;  
  4. [self.view addGestureRecognizer:doubleTap_];  

看看响应的方法:
[cpp] view plain copy
  1. /* 双击手势的响应方法 */  
  2. -(void)enlargePDFPage:(id)sender {  
  3.     if (enlarged_ == NO) { // 如果PDF页面未被放大  
  4.         [curView removeFromSuperview];     //首先移除当前PDF页面  
  5.         [self.view addSubview:scrollView]; // 在self.view中添加scrollView  
  6.         [scrollView addSubview:curView];   // 在scrollView上重新添加curView  
  7.         curView.frame = pdfRect_; // 设置curView的框架为原始PDF视图的框架  
  8.         scrollView.contentSize = pdfRect_.size; // 设置scrollView的内容尺寸  
  9.         enlarged_ = YES; // 设置放大状态  
  10.         self.navigationController.navigationBarHidden = YES; // 隐藏导航条  
  11.     }  
  12.     else { // 如果PDF页面已经被放大  
  13.         [scrollView removeFromSuperview]; // 移除scrollView和curView  
  14.         [viewForPDF addSubview:curView]; // 在viewForPDF子视图重新添加curView  
  15.         curView.frame = fitRect_;  
  16.         enlarged_ = NO; // 取消放大状态  
  17.         self.navigationController.navigationBarHidden = NO; // 显示导航条  
  18.     }  
  19. }  
这样一来,在双击视图后,就可以查看全屏状态下的pdf视图了:


在全屏状态下再次双击视图,又看到原来的PDFView了:



最后解决一下翻页的问题,这里我沿用了之前的方法:

[cpp] view plain copy
  1. #pragma mark -  
  2. #pragma mark Touches in view  
  3.   
  4. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  
  5.     //记录手势起点的x值  
  6.     UITouch *touch = [touches anyObject];  
  7.     startX_        = [touch locationInView:self.view].x;  
  8. }  
  9.   
  10. -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {  
  11.     //将视图中已经存在的渐变或页边阴影去掉  
  12.     if (shadow) {  
  13.         [shadow removeFromSuperlayer];  
  14.     }  
  15.     if (margin) {  
  16.         [margin removeFromSuperlayer];  
  17.     }  
  18.       
  19.     //获取当前手势触点的x值  
  20.     UITouch *touch = [touches anyObject];  
  21.     float x        = [touch locationInView:self.view].x;  
  22.     if (x - startX_ >= 0) {  
  23.         curoffset_ = x - startX_;  
  24.     }  
  25.     else {  
  26.         curoffset_ = startX_ - x;  
  27.     }  
  28.       
  29.     // 设定翻转页面的矩形范围  
  30.     CGRect rect = self.view.bounds;  
  31.     if (x >= 160) {  
  32.         rect.size.width = (320 / x - 1) * 160;  
  33.         rect.origin.x   = x - rect.size.width;  
  34.     }  
  35.     else {  
  36.         rect.size.width = 320 - x;  
  37.         rect.origin.x   = x - rect.size.width;  
  38.     }  
  39.     int tempX           = rect.origin.x; //保存翻转页面起点的x值  
  40.     backView.frame      = rect;  
  41.       
  42.     //rect用于设定翻页时左边页面的范围  
  43.     rect = self.view.bounds;  
  44.     rect.size.width = x;  
  45.       
  46.       
  47.     // 判断手势并设定页面,制造翻页效果  
  48.     if (x - startX_ > 0) { //向右划的手势,上一页  
  49.         next_ = NO;  
  50.         if (currentPage_ == 1) {  
  51.             return// 如果是第一页则不接受手势  
  52.         }  
  53.         else {  
  54.             addView.frame = rect;  
  55.             addView.clipsToBounds = YES;  
  56.             addView.pageIndex = currentPage_ - 1;  
  57.             [addView reloadView];  
  58.               
  59.             [viewForPDF insertSubview:addView aboveSubview:curView];  
  60.               
  61.             [viewForPDF insertSubview:backView aboveSubview:addView];  
  62.         }  
  63.     }  
  64.     else { //向左划的手势,下一页  
  65.         next_ = YES;  
  66.           
  67.         if (currentPage_ == totalPages_) {  
  68.             return// 如果到达最后一页则不接受手势  
  69.         }  
  70.         else {  
  71.             curView.frame = rect;  
  72.             addView.pageIndex = currentPage_ + 1;  
  73.             addView.frame = fitRect_;  
  74.             [addView reloadView];  
  75.               
  76.             [viewForPDF insertSubview:addView belowSubview:curView];  
  77.               
  78.             [viewForPDF insertSubview:backView aboveSubview:curView];  
  79.         }  
  80.     }  
  81.       
  82.     //设定翻页时backPage视图两边的渐变阴影效果  
  83.     shadow            = [[CAGradientLayer alloc] init];  
  84.     shadow.colors     = [NSArray arrayWithObjects:  
  85.                          (id)[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1].CGColor,  
  86.                          (id)[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.2].CGColor,  
  87.                          (id)[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1].CGColor,  
  88.                          nil];  
  89.     rect              = self.view.bounds;  
  90.     rect.size.width   = 50;  
  91.     rect.origin.x     = x - 25;  
  92.     shadow.frame      = rect;  
  93.     shadow.startPoint = CGPointMake(0.0, 0.5);  
  94.     shadow.endPoint   = CGPointMake(1.0, 0.5);  
  95.     [self.view.layer addSublayer:shadow];  
  96.       
  97.     margin            = [[CAGradientLayer alloc] init];  
  98.     margin.colors     = [NSArray arrayWithObjects:  
  99.                          (id)[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.2].CGColor,  
  100.                          (id)[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3].CGColor,  
  101.                          nil];  
  102.     margin.frame      = CGRectMake(tempX - 35, 0, 50, self.view.bounds.size.height);  
  103.     margin.startPoint = CGPointMake(0.0, 0.5);  
  104.     margin.endPoint   = CGPointMake(1.0, 0.5);  
  105.     [self.view.layer addSublayer:margin];  
  106. }  
  107.   
  108. -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
  109.     // 如果是第一页并且翻向上一页  
  110.     if (currentPage_ == 1) {  
  111.         if (next_ == NO) {  
  112.             return;  
  113.         }  
  114.     }  
  115.       
  116.     // 如果是最后一页并且翻向下一页  
  117.     if (currentPage_ == totalPages_) {  
  118.         if (next_ == YES) {  
  119.             UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"注意" message:@"已经到达最后一页" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];  
  120.             [av show];  
  121.             return;  
  122.         }  
  123.     }  
  124.       
  125.     if (curoffset_ < minoffset_) {  
  126.         curView.frame = fitRect_;  
  127.         curView.pageIndex = currentPage_ ;  
  128.         [curView reloadView];  
  129.           
  130.         [addView  removeFromSuperview];  
  131.         [backView removeFromSuperview];  
  132.           
  133.         //移除阴影效果  
  134.         [shadow removeFromSuperlayer];  
  135.         [margin removeFromSuperlayer];  
  136.           
  137.         return;  
  138.     }  
  139.       
  140.     if (next_ == YES) { // 下一页  
  141.         currentPage_++;  
  142.         NSLog(@"%d / %d", currentPage_, totalPages_);  
  143.         curView.frame = fitRect_;  
  144.         curView.pageIndex = currentPage_;  
  145.         [curView reloadView];  
  146.           
  147.         self.navigationItem.title = [NSString stringWithFormat:@"%d / %d", currentPage_, totalPages_];  
  148.     }  
  149.     else { // 上一页  
  150.         currentPage_--;  
  151.         NSLog(@"%d / %d", currentPage_, totalPages_);  
  152.         curView.frame = fitRect_;  
  153.         curView.pageIndex = currentPage_;  
  154.         [curView reloadView];  
  155.           
  156.         self.navigationItem.title = [NSString stringWithFormat:@"%d / %d", currentPage_, totalPages_];  
  157.     }  
  158.       
  159.     [addView  removeFromSuperview];  
  160.     [backView removeFromSuperview];  
  161.       
  162.     //移除阴影效果  
  163.     [shadow removeFromSuperlayer];  
  164.     [margin removeFromSuperlayer];  
  165. }  

原理和Reader开发(一)中的翻页效果原理是一样的,最后还是上张程序运行的图:




至此,实现PDF阅读的基本功能已经实现,不需要考虑分页的问题,对于获取PDF上面的内容可能要用到Core Text,这样可能要用另一种思维来写,暂时到此为止吧,如果对于这方面有什么新想法我会继续改进并且更新博客的。

以上关于PDF文件阅读的代码参考了网上的一些文章,大家也可以参考一下:

http://blog.csdn.net/yiyaaixuexi/article/details/7645725

http://2015.iteye.com/blog/1333272

http://www.cnblogs.com/mainPage/archive/2010/10/22/1858666.html

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 衣服混洗染色了怎么办 黑裤子洗成红色怎么办 衣服烘干后皱了怎么办 毛衣洗了变长了怎么办 boy烫金被洗掉了怎么办 黑衣服洗得发白怎么办 黑衣服洗后发白怎么办 黑裤子洗了发白怎么办 黑衣服旧了发白怎么办 黑色衣服洗白了怎么办 黑衣服洗了泛白怎么办 刚买的衣服掉色怎么办 棉质的衣服褪色怎么办 黑裤子晒掉色了怎么办 新买的衣服褪色怎么办 衣服洗了掉毛怎么办 衣服受潮长了斑点怎么办 黑色的衣服粘毛怎么办 黑衣服容易粘毛怎么办 衣服上粘了毛毛怎么办 黑衣服防止粘毛怎么办 洗黑色衣服掉毛怎么办 兔毛的衣服掉毛怎么办 带绒的衣服掉毛怎么办 黑裤子被84掉色怎么办 买的衣服掉毛怎么办 裤子穿久了泛亮怎么办 新买的裤子褪色怎么办 黑裤子掉毛严重怎么办 黑裤子洗完发白怎么办 新买羊绒衫掉毛怎么办 皮草毛卷起来了怎么办 小孩衣服洗不干净怎么办 衣服沾上钢笔水怎么办 羊绒衫洗了掉毛怎么办 白衬衫弄上墨水怎么办 羊毛衬衫洗错了怎么办 婚纱照拍的太丑怎么办 微信加人没反应怎么办 新买的毛毯有味怎么办 科二第一次练车怎么办