iOS 仿騰訊視頻分類編輯頁(yè)面實(shí)現(xiàn)

現(xiàn)在一些常用的App都有分類功能,為了讓用戶方便的編輯自己喜好的分類標(biāo)簽,相應(yīng)的要有分類編輯頁(yè)。以下內(nèi)容簡(jiǎn)單的介紹了如何實(shí)現(xiàn)類似騰訊視頻、今日頭條的內(nèi)容分類標(biāo)簽編輯功能。本篇文章主要講使用UICollectionView如何實(shí)現(xiàn)分類標(biāo)簽編輯功能,分為使用iOS9以后系統(tǒng)自帶的新特性實(shí)現(xiàn),使用UICollectionView自定義方式實(shí)現(xiàn)。主要涉及到的技術(shù)點(diǎn)有:UICollectionView的Cell移動(dòng)、長(zhǎng)按手勢(shì)識(shí)別、NSArray數(shù)組操作、控件封裝、數(shù)據(jù)本地持久化、文件管理等等

下載Demo

一、思考實(shí)現(xiàn)方式

1、使用UIButtonUIScrollView實(shí)現(xiàn):這種方式需要?jiǎng)?chuàng)建很多UIButton按鈕,不斷的更新按鈕的布局;
2、使用UICollectionView 的iOS9以后系統(tǒng)自帶的新特性實(shí)現(xiàn):簡(jiǎn)單快捷,但是無(wú)法支持iOS9以下的設(shè)備;
3、使用UICollectionView實(shí)現(xiàn)布局,標(biāo)簽移動(dòng)通過(guò)開(kāi)發(fā)者自己控制實(shí)現(xiàn):兼容性好,開(kāi)發(fā)者可控性強(qiáng),需要自定義一個(gè)與選中cell內(nèi)容相同ShowView展示給用戶,ShowView的位置隨手勢(shì)的移動(dòng)改變,手勢(shì)結(jié)束后ShowView消失,此時(shí)顯示真正的cell;

二、實(shí)現(xiàn)運(yùn)行效果

IMG_0067.GIF

三、創(chuàng)建UICollectionView

這個(gè)很簡(jiǎn)單,大家已經(jīng)使用的很熟練了,就不再過(guò)多介紹了。

/* UICollectionView的布局layout */
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
CGFloat cellWidth = (CGRectGetWidth(self.view.frame) - (kColumnNumner + 1)*kItemMarginX)/kColumnNumner;
CGFloat cellHeight = cellWidth/2.0f;
_flowLayout.itemSize = CGSizeMake(cellWidth, cellHeight);
_flowLayout.sectionInset = UIEdgeInsetsMake(kItemMarginY, kItemMarginX, kItemMarginY, kItemMarginX);
_flowLayout.minimumLineSpacing = kItemMarginY;
_flowLayout.minimumInteritemSpacing = kItemMarginX;
_flowLayout.headerReferenceSize = CGSizeMake(CGRectGetWidth(self.view.frame), 60);
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(lineView.frame), CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) - CGRectGetMaxY(lineView.frame)) collectionViewLayout:_flowLayout];
self.collectionView.backgroundColor = [UIColor clearColor];
self.collectionView.showsHorizontalScrollIndicator = YES; 
/* 注冊(cè)cell */   
[self.collectionView registerNib:[UINib nibWithNibName:@"WSClassifyEditViewCell" bundle:nil] forCellWithReuseIdentifier:@"WSClassifyEditViewCell"];
/* 注冊(cè)SectionHeader */
[self.collectionView registerClass:[WSClassifyHeaderView class]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"WSClassifyHeaderView"];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];

四、為UICollectionView添加長(zhǎng)按手勢(shì)

UICollectionView添加長(zhǎng)按手勢(shì)UILongPressGestureRecognizer,addGestureRecognizer添加手勢(shì)到UICollectionView上,handleLongPressGesture為長(zhǎng)按手勢(shì)事件觸發(fā)方法,通過(guò)監(jiān)聽(tīng)長(zhǎng)按手勢(shì)的Began、Changed、Cancelled、Ended實(shí)現(xiàn)選中cell的移動(dòng)功能。

長(zhǎng)按手勢(shì)移動(dòng)cell思路:

1、長(zhǎng)按選中的需要移動(dòng)拖動(dòng)的cell,longGesture的狀態(tài)變?yōu)?code>begin,通過(guò)手勢(shì)locationInView獲取當(dāng)前點(diǎn)擊位置point,初始化一個(gè)專門用于顯示的ShowView,ShowView的位置隨point的改變而變化,也就是說(shuō)ShowView需要跟隨手勢(shì)ShowView.center=point;
2、拖動(dòng)cell此時(shí)手勢(shì)的狀態(tài)變?yōu)?code>Changed,通過(guò)手勢(shì)``locationInView獲取的當(dāng)前位置改變,ShowView的位置隨之變化;
3、通過(guò)ShowView的位置找到和cell交換的targetCell的位置;
4、交換celltargetCell的位置;
5、處理數(shù)據(jù)結(jié)構(gòu),這里是對(duì)兩個(gè)數(shù)組進(jìn)行操作;

添加手勢(shì):

_longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
_longGesture.delegate = self;
[self.collectionView addGestureRecognizer:_longGesture];

手勢(shì)觸發(fā):

- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)gestureRecognizer {
CGPoint point = [gestureRecognizer
locationInView:self.collectionView];
switch (gestureRecognizer.state) {
  case UIGestureRecognizerStateBegan:  
       [self dragItemBegin:point];
       break;
  case UIGestureRecognizerStateChanged:
       [self dragItemChanged:point];
       break;
  case UIGestureRecognizerStateCancelled:
       [self dragItemCancelled];
       break;
  case UIGestureRecognizerStateEnded:
       [self dragItemEnd];
       break;
  default:
       break;
    }
}

五、手勢(shì)事件實(shí)現(xiàn)

開(kāi)始長(zhǎng)按手勢(shì)Begin

自定義方法實(shí)現(xiàn):
1、通過(guò)locationInView獲取點(diǎn)擊位置point;
2、根據(jù)point獲取當(dāng)前選中cell的位置NSIndexPath *currentIndexPath;
3、判斷點(diǎn)擊范圍;
4、再根據(jù)currentIndexPath獲取選中的cell實(shí)例;
5、創(chuàng)建個(gè)輔助顯示的ShowView,根據(jù)選中的cell獲取的截圖image,將image貼到ShowView中,選中cell隱藏,并對(duì)ShowView添加一個(gè)放大動(dòng)畫,讓ShowView隨著手勢(shì)移動(dòng)而不是cell在移動(dòng);

//第一步:通過(guò)locationInView獲取點(diǎn)擊位置point;
CGPoint point = [gestureRecognizer locationInView:self.collectionView];
- (void)dragItemBegin:(CGPoint)point
{
    //第二步:根據(jù)point獲取當(dāng)前選中cell的位置NSIndexPath *currentIndexPath;
    NSIndexPath *currentIndexPath = [self.collectionView indexPathForItemAtPoint:point];  
    //第三步:判斷點(diǎn)擊范圍;
    if (![self collectionView:self.collectionView canMoveItemAtIndexPath:currentIndexPath]) {
        return;
    }
    self.selectedIndexPath = currentIndexPath;
    //第四步:再根據(jù)currentIndexPath獲取選中的cell實(shí)例;
    WSClassifyEditViewCell *viewcell = (WSClassifyEditViewCell *)[self.collectionView cellForItemAtIndexPath:self.selectedIndexPath];
    //第五步:創(chuàng)建個(gè)輔助顯示的ShowView,根據(jù)選中的cell獲取cell的截圖image,將image貼到ShowView中,選中cell隱藏,并對(duì)ShowView添加一個(gè)放大動(dòng)畫,讓ShowView隨著手勢(shì)移動(dòng)而不是cell在移動(dòng)
    self.showView = [[UIView alloc] initWithFrame:viewcell.frame];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[self getImageContext:viewcell]];
    imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.showView addSubview:imageView];
    [self.collectionView addSubview:self.currentView];
    viewcell.isMoving = YES;
    [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.currentView.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
        } completion:^(BOOL finished) {
        }];
}

使用iOS9以后系統(tǒng)自帶的新特性實(shí)現(xiàn):
手勢(shì)狀態(tài)為begin時(shí)只需一句話,蠻簡(jiǎn)單!

[self.collectionView beginInteractiveMovementForItemAtIndexPath:self.selectedIndexPath];

長(zhǎng)按手勢(shì)拖動(dòng)變化Changed:

自定義方法實(shí)現(xiàn):
1、通過(guò)locationInView獲取手勢(shì)移動(dòng)位置point;
2、更新showView的位置;
3、獲取將要交換的目標(biāo)位置的IndexPath;
4、判斷showView移動(dòng)到的target位置是否需要交換位置;
5、處理內(nèi)存中的數(shù)據(jù),交換數(shù)據(jù)位置;
6、選中cell與targetCell交換位置;
7、將記錄選中位置的變量selectedIndexPath進(jìn)行更新為新位置;

//第一步:通過(guò)locationInView獲取手勢(shì)移動(dòng)位置point;
CGPoint point = [gestureRecognizer locationInView:self.collectionView];

-(void)dragItemChanged:(CGPoint)point{
//第二步:更新showView的位置
self.showView.center = point;
//第三步:獲取將要交換的目標(biāo)位置的IndexPath
NSIndexPath *newIndexPath = [self.collectionView indexPathForItemAtPoint:self.showView.center];
//當(dāng)前選中cell的位置,selectedIndexPath是通過(guò)第一步定位操作獲取的,用于保存正在被拖動(dòng)cell的indexPath
NSIndexPath *previousIndexPath = self.selectedIndexPath;
//第四步:判斷showView移動(dòng)到的target位置是否需要交換位置;
if (![self collectionView:_collectionView itemAtIndexPath:previousIndexPath canMoveToIndexPath:newIndexPath]) {
return;
}
//第五步:處理內(nèi)存中的數(shù)據(jù),交換數(shù)據(jù)位置;
id obj = [self.displayArray objectAtIndex:self.selectedIndexPath.row];
[self.displayArray removeObject:obj];
[self.displayArray insertObject:obj atIndex:newIndexPath.row];
//第六步:選中cell與targetCell交換位置;
[self.collectionView moveItemAtIndexPath:previousIndexPath toIndexPath:newIndexPath];
//第七步:將記錄選中位置的變量selectedIndexPath進(jìn)行更新為新位置;
self.selectedIndexPath = newIndexPath;
}

第四步中的判斷`showView`移動(dòng)到目標(biāo)位置是否需要交換位置的方法

  • (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath
    {
    //移動(dòng)到顯示分組的第一個(gè)位置時(shí)不需要交換位置
    if (toIndexPath.section == 0) {
    if (toIndexPath.row == 0) {
    return NO;
    }
    }
    else if (toIndexPath.section == 1){
    //移動(dòng)到未顯示分組時(shí)不需要交換位置
    return NO;
    }
    return YES;
    }
>使用`iOS9`以后系統(tǒng)自帶的新特性實(shí)現(xiàn):
>手勢(shì)狀態(tài)為`Changed`時(shí)只需一句話,蠻簡(jiǎn)單!

CGPoint point = [gestureRecognizer locationInView:self.collectionView];
[self.collectionView updateInteractiveMovementTargetPosition:point];

長(zhǎng)按手勢(shì)拖動(dòng)變化結(jié)束`Ended`:

>使用自定義方法實(shí)現(xiàn):
>1、通過(guò)記錄當(dāng)前位置的`selectedIndexPath`獲取當(dāng)前位置的`frame`;
>2、將`showView`的`frame`置未第一步中獲取的`frame`,模擬`cell`復(fù)位;
>3、清空輔助`showView`,并顯示`cell`;
>```
-(void)dragItemEnd
{
  //第一步:通過(guò)記錄當(dāng)前位置的selectedIndexPath獲取當(dāng)前位置的frame;
  WSClassifyEditViewCell *viewcell = (WSClassifyEditViewCell *)     [self.collectionView cellForItemAtIndexPath:self.selectedIndexPath];
        CGRect endFrame = viewcell.frame;
        [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
          //第二步:將showView的frame置未第一步中獲取的frame,模擬cell復(fù)位
            self.showView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
            self.showView.frame = endFrame;
        }completion:^(BOOL finished) {
        //清空輔助showView,并顯示cell;
            [self.showView removeFromSuperview];
            self.showView = nil;
            viewcell.isMoving = NO;
            [self.flowLayout invalidateLayout];
        }];  
}

使用iOS9以后系統(tǒng)自帶的新特性實(shí)現(xiàn):
手勢(shì)狀態(tài)為Ended時(shí)也只需一句話,蠻簡(jiǎn)單!

[self.collectionView endInteractiveMovement];

六、點(diǎn)擊cell實(shí)現(xiàn)加減功能

在編輯狀態(tài)下點(diǎn)擊顯示分組的cell,在顯示分組中刪除,將選中的cell移動(dòng)到未顯示分組中,并且恢復(fù)到添加前的位置。點(diǎn)擊未顯示分組的cell,在未顯示分組中刪除,將被選中的cell添加到顯示分組中;

主要思路:
1、需要實(shí)現(xiàn)分類標(biāo)簽數(shù)據(jù)的本地持久化存儲(chǔ),我將全部標(biāo)簽存在沙盒目錄下的allSorts.plist中,同時(shí)將已經(jīng)顯示的分類標(biāo)簽存在沙盒目錄下的displaySort.plist中,每次顯示分類編輯頁(yè)的時(shí)候?qū)山M數(shù)據(jù)取出,對(duì)比兩組數(shù)據(jù)獲取未顯示分類標(biāo)簽數(shù)據(jù)。并且實(shí)現(xiàn)總分類標(biāo)簽因服務(wù)器數(shù)據(jù)出現(xiàn)增減標(biāo)簽時(shí)與本地?cái)?shù)據(jù)合并的功能,新分類標(biāo)簽在下次啟動(dòng)時(shí)顯示;

1、合并服務(wù)器數(shù)據(jù),解決數(shù)據(jù)增減問(wèn)題:

/// 判斷本地?cái)?shù)據(jù)與服務(wù)端數(shù)據(jù)是否相同
/// @param locals 本地?cái)?shù)據(jù)
/// @param remotes 服務(wù)器返回?cái)?shù)據(jù)
- (BOOL)equalLocal:(NSArray *)locals remote:(NSArray *)remotes
{
    //查詢到在locals中,不在數(shù)組remotes中的數(shù)據(jù)
    NSPredicate *localFilterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",remotes];
    NSArray *localFilter = [locals filteredArrayUsingPredicate:localFilterPredicate];
    [self.reduceObjects addObjectsFromArray:localFilter];
    //查詢到在remotes中,不在數(shù)組locals中的數(shù)據(jù)
    NSPredicate *remoteFilterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",locals];
    NSArray *remoteFilter = [remotes filteredArrayUsingPredicate:remoteFilterPredicate];
    [self.addObjects addObjectsFromArray:remoteFilter];
    //拼接數(shù)組,所有變化的數(shù)據(jù),若array內(nèi)容為空,則數(shù)組未改變
    NSMutableArray *array = [NSMutableArray arrayWithArray:localFilter];
    [array addObjectsFromArray:remoteFilter];
    if (array.count>0) {
        return YES;
    }
    return NO;
}

2、通過(guò)比較全部標(biāo)簽數(shù)據(jù)與已顯示標(biāo)簽數(shù)據(jù),獲取未顯示標(biāo)簽:

/// 獲取未顯示數(shù)據(jù)
- (NSArray *)getNoDisplayArray
{
    NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",self.displayArray];
    NSArray *resultArray = [self.allSortArray filteredArrayUsingPredicate:filterPredicate];
    return resultArray;
}

3、處理分類更新數(shù)據(jù)變化,點(diǎn)擊 cell進(jìn)行增刪時(shí)使用:

這個(gè)方法在數(shù)據(jù)管理類中實(shí)現(xiàn),將處理完的結(jié)果向UI層拋出回調(diào),實(shí)現(xiàn)是數(shù)據(jù)與UI的分離

/**
 處理分類更新數(shù)據(jù)變化
*/
- (void)handleUpdateSortAtIndexPath:(NSIndexPath *)indexPath complete:(void(^)(NSArray *displayDatas,NSArray *noDisplayDatas,NSInteger row))complateBlock
{
    NSInteger row = 0;
    if (indexPath.section == 0) {
        id obj = [self.displayArray objectAtIndex:indexPath.row];
        [self.displayArray removeObject:obj];
        self.noDisplayArray = (NSMutableArray *)[self getNoDisplayArray];
        row = [self.noDisplayArray indexOfObject:obj];
    }
    else if (indexPath.section == 1){
        id obj = [self.noDisplayArray objectAtIndex:indexPath.row];
        [self.displayArray addObject:obj];
        self.noDisplayArray = (NSMutableArray *)[self getNoDisplayArray];
        row = self.displayArray.count - 1;
    }
    [self saveSortData:self.displayArray plistPath:self.displayPlistPath];
    complateBlock(self.displayArray,self.noDisplayArray,row);
}

4、UI層中對(duì)cell增刪的處理

if ([self.delegate respondsToSelector:@selector(selectItemAtIndexPath:complete:)]) {
                @weakify(self)
                [self.delegate selectItemAtIndexPath:indexPath complete:^(NSArray * _Nonnull displayDatas, NSArray * _Nonnull noDisplayDatas, NSInteger row) {
                    @strongify(self)
                    self.displayArray = (NSMutableArray *)displayDatas;
                    self.noDisplayArray = (NSMutableArray *)noDisplayDatas;
                    NSIndexPath * targetIndexPath = [NSIndexPath indexPathForRow:row inSection:1];
                    [self handleMoveItemIndex:indexPath targetIndex:targetIndexPath];
                }];
            }

七、相關(guān)代理回調(diào)

1、基礎(chǔ)回調(diào)方法:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 2;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    if (section == 0) {
        return self.displayArray.count;
    }
    else if (section == 1){
        return self.noDisplayArray.count;
    }
    return 0;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if (kind == UICollectionElementKindSectionHeader) {
        WSClassifyHeaderView *header = (WSClassifyHeaderView *)[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"WSClassifyHeaderView" forIndexPath:indexPath];
        [header buildHeaderView:indexPath.section];
        return header;
    }
    return [[UICollectionReusableView alloc] init];
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString* cellId = @"WSClassifyEditViewCell";
    WSClassifyEditViewCell *itemCell = (WSClassifyEditViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
    [itemCell sizeToFit];
    if (indexPath.section == 0) {
        [itemCell bindViewModel:self.displayArray[indexPath.row] indexPath:indexPath];
    }
    else if (indexPath.section == 1){
        [itemCell bindViewModel:self.noDisplayArray[indexPath.row] indexPath:indexPath];
    }
    itemCell.markHiden = self.editBtn.hidden;
    return itemCell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
  //在這里實(shí)現(xiàn)點(diǎn)擊事件
}

2、只有使用iOS9以后系統(tǒng)自帶的新特性實(shí)現(xiàn)時(shí)使用:

- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath
{
    /**
     * sourceIndexPath 原始數(shù)據(jù) indexpath
     * destinationIndexPath 移動(dòng)到目標(biāo)數(shù)據(jù)的 indexPath
    */
    NSInteger soureceIndex = sourceIndexPath.row;
    NSInteger destinaIndex = destinationIndexPath.row;
    NSString *item = [self.displayArray objectAtIndex:soureceIndex];
    [self.displayArray removeObjectAtIndex:soureceIndex];
    [self.displayArray insertObject:item atIndex:destinaIndex];
}
- (NSIndexPath *)collectionView:(UICollectionView *)collectionView targetIndexPathForMoveFromItemAtIndexPath:(NSIndexPath *)originalIndexPath toProposedIndexPath:(NSIndexPath *)proposedIndexPath
{
    //此地處理cell滑動(dòng)到Top分組第一個(gè)位置不移動(dòng),滑動(dòng)到bottom分組任何位置不移動(dòng)
    if (proposedIndexPath.section == 0) {
        if (proposedIndexPath.item == 0) {
            return originalIndexPath;
        }
    }
    else if (proposedIndexPath.section == 1){
        return originalIndexPath;
    }
    return proposedIndexPath;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == 0) {
        return NO;
    }
    else if(indexPath.section == 1){
        return NO;
    }
    return YES;
}

注:在通過(guò)全部標(biāo)簽數(shù)據(jù)和已顯示標(biāo)簽數(shù)據(jù)比較獲取未顯示分類標(biāo)簽數(shù)據(jù)時(shí)使用了NSPredicate謂詞查詢,這里碰到了一個(gè)小問(wèn)題,在UI層處理時(shí)數(shù)據(jù)都已經(jīng)被處理為model實(shí)例化模型,導(dǎo)致了使用NSPredicate時(shí)沒(méi)有過(guò)濾出想要的數(shù)據(jù),所以我將數(shù)據(jù)處理放到了管理類中,在管理類中的數(shù)據(jù)還是原始模型(字典類型),這樣再使用NSPredicate過(guò)濾時(shí)就沒(méi)有出現(xiàn),數(shù)據(jù)內(nèi)容相同但地址不同時(shí)無(wú)法過(guò)濾的問(wèn)題了; 建議使用自定義cell移動(dòng)的方法實(shí)現(xiàn)分類標(biāo)簽編輯頁(yè),這樣比使用iOS9以后系統(tǒng)提供的結(jié)構(gòu)能更好的控制效果,并且兼容性更好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容