【低耦合集成TabBarController】最低只需傳兩個(gè)數(shù)組即可完成主流App框架搭建

CYLTabBarController【低耦合集成TabBarController】

<p align="center">


enter image description here
enter image description here

enter image description here
enter image description here

enter image description here
enter image description here

</a>

<p align="center">

bitHound

Gitter
Gitter

</a>

導(dǎo)航

  1. 與其他自定義TabBarController的區(qū)別
  2. 集成后的效果
  3. 項(xiàng)目結(jié)構(gòu)
  4. 使用CYLTabBarController
  5. 第一步:使用CocoaPods導(dǎo)入CYLTabBarController
  6. 第二步:設(shè)置CYLTabBarController的兩個(gè)數(shù)組:控制器數(shù)組和TabBar屬性數(shù)組
  7. 第三步:將CYLTabBarController設(shè)置為window的RootViewController
  8. 第四步(可選):創(chuàng)建自定義的形狀不規(guī)則加號(hào)按鈕
  9. 補(bǔ)充說明
  10. 自定義 TabBar 樣式
  11. 橫豎屏適配
  12. 訪問初始化好的 CYLTabBarController 對(duì)象
  13. 點(diǎn)擊 PlusButton 跳轉(zhuǎn)到指定 UIViewController
  14. 讓TabBarItem僅顯示圖標(biāo),并使圖標(biāo)垂直居中
  15. 在 Swift 項(xiàng)目中使用 CYLTabBarController
  16. 源碼實(shí)現(xiàn)原理
  17. Q-A

與其他自定義TabBarController的區(qū)別

- 特點(diǎn) 解釋
1 低耦合,易刪除 1、TabBar設(shè)置與業(yè)務(wù)完全分離,最低只需傳兩個(gè)數(shù)組即可完成主流App框架搭建。</p> 2、 PlusButton 的所有設(shè)置都在單獨(dú)的一個(gè)類( CYLPlusButton 的子類)中實(shí)現(xiàn):刪除該特定的類,就能完全將 PlusButton 從項(xiàng)目中刪除掉。
2 TabBar 以及 TabBar 內(nèi)的 TabBarItem 均使用系統(tǒng)原生的控件 因?yàn)槭褂迷目丶?,并?UIButtonUIView 。好處如下:</p> 1. 無(wú)需反復(fù)調(diào)“間距位置等”來(lái)接近系統(tǒng)效果。</p> 2. 在push到下一頁(yè)時(shí) TabBar 的隱藏和顯示之間的過渡效果跟系統(tǒng)一致(詳見“ 集成后的效果 ”部分,給出了效果圖) </p> 3. 原生控件,所以可以使用諸多系統(tǒng)API,比如:可以使用 [UITabBar appearance]; 、[UITabBarItem appearance]; 設(shè)置樣式。(詳見“補(bǔ)充說明 ”部分,給出了響應(yīng)代碼示例)
3 自動(dòng)監(jiān)測(cè)是否需要添加“加號(hào)”按鈕,</p>并能自動(dòng)設(shè)置位置 CYLTabBarController 既支持類似微信的“中規(guī)中矩”的 TabBarController 樣式,并且默認(rèn)就是微信這種樣式,同時(shí)又支持類似“微博”或“淘寶閑魚”這種具有不規(guī)則加號(hào)按鈕的 TabBarController 。想支持這種樣式,只需自定義一個(gè)加號(hào)按鈕,CYLTabBarController 能檢測(cè)到它的存在并自動(dòng)將 tabBar 排序好,無(wú)需多余操作,并且也預(yù)留了一定接口來(lái)滿足自定義需求。</p>“加號(hào)”按鈕的樣式、frame均在自定義的類中獨(dú)立實(shí)現(xiàn),不會(huì)涉及tabbar相關(guān)設(shè)置。
4 即使加號(hào)按鈕超出了tabbar的區(qū)域,</p>超出部分依然能響應(yīng)點(diǎn)擊事件 紅線內(nèi)的區(qū)域均能響應(yīng)tabbar相關(guān)的點(diǎn)擊事件,</p>
enter image description here
5 允許指定加號(hào)按鈕位置 效果如下:</p>
enter image description here
</p>Airbnb-app效果:</p>
enter image description here
6 支持讓 TabBarItem 僅顯示圖標(biāo),并自動(dòng)使圖標(biāo)垂直居中,支持自定義TabBar高度 效果可見Airbnb-app效果,或者下圖</p>
enter image description here
enter image description here
7 支持CocoaPods 容易集成
8 支持Swift項(xiàng)目導(dǎo)入 兼容
9 支持橫豎屏 --

(學(xué)習(xí)交流群:561873398)

集成后的效果:

既支持默認(rèn)樣式 同時(shí)也支持創(chuàng)建自定義的形狀不規(guī)則加號(hào)按鈕
enter image description here
enter image description here

支持橫豎屏


enter image description here
本倉(cāng)庫(kù)配套Demo的效果: 另一個(gè)Demo 使用CYLTabBarController實(shí)現(xiàn)了微博Tabbar框架,效果如下
enter image description here
enter image description here

項(xiàng)目結(jié)構(gòu)

enter image description here

做下說明:


├── CYLTabBarController  #核心庫(kù)文件夾,如果不使用 CocoaPods 集成,請(qǐng)直接將這個(gè)文件夾拖拽帶你的項(xiàng)目中
└── Example
   └── Classes
       ├── Module       #模塊類文件夾
       │   ├── Home
       │   ├── Message
       │   ├── Mine
       │   └── SameCity
       └── View         #這里放著 CYLPlusButton 的子類 CYLPlusButtonSubclass,演示了如何創(chuàng)建自定義的形狀不規(guī)則加號(hào)按鈕
       
       

使用CYLTabBarController

四步完成主流App框架搭建:

  1. 第一步:使用CocoaPods導(dǎo)入CYLTabBarController
  2. 第二步:設(shè)置CYLTabBarController的兩個(gè)數(shù)組:控制器數(shù)組和TabBar屬性數(shù)組
  3. 第三步:將CYLTabBarController設(shè)置為window的RootViewController
  4. 第四步(可選):創(chuàng)建自定義的形狀不規(guī)則加號(hào)按鈕

第一步:使用CocoaPods導(dǎo)入CYLTabBarController

Podfile 中進(jìn)行如下導(dǎo)入:

pod 'CYLTabBarController'

然后使用 cocoaPods 進(jìn)行安裝:

如果尚未安裝 CocoaPods, 運(yùn)行以下命令進(jìn)行安裝:

gem install cocoapods

安裝成功后就可以安裝依賴了:

建議使用如下方式:

# 禁止升級(jí)CocoaPods的spec倉(cāng)庫(kù),否則會(huì)卡在 Analyzing dependencies ,非常慢 
pod update --verbose --no-repo-update

如果提示找不到庫(kù),則可去掉 --no-repo-update

pod update

第二步:設(shè)置CYLTabBarController的兩個(gè)數(shù)組:控制器數(shù)組和TabBar屬性數(shù)組

- (void)setupViewControllers {
   CYLHomeViewController *firstViewController = [[CYLHomeViewController alloc] init];
   UIViewController *firstNavigationController = [[UINavigationController alloc]
                                                  initWithRootViewController:firstViewController];
   
   CYLSameFityViewController *secondViewController = [[CYLSameFityViewController alloc] init];
   UIViewController *secondNavigationController = [[UINavigationController alloc]
                                                   initWithRootViewController:secondViewController];
   

   CYLTabBarController *tabBarController = [[CYLTabBarController alloc] init];
   [self customizeTabBarForController:tabBarController];
   
   [tabBarController setViewControllers:@[
                                          firstNavigationController,
                                          secondNavigationController,
                                          ]];
   self.tabBarController = tabBarController;
}

/*
*
在`-setViewControllers:`之前設(shè)置TabBar的屬性,
*
*/
- (void)customizeTabBarForController:(CYLTabBarController *)tabBarController {
   
   NSDictionary *dict1 = @{
                           CYLTabBarItemTitle : @"首頁(yè)",
                           CYLTabBarItemImage : @"home_normal",
                           CYLTabBarItemSelectedImage : @"home_highlight",
                           };
   NSDictionary *dict2 = @{
                           CYLTabBarItemTitle : @"同城",
                           CYLTabBarItemImage : @"mycity_normal",
                           CYLTabBarItemSelectedImage : @"mycity_highlight",
                           };

   NSArray *tabBarItemsAttributes = @[ dict1, dict2 ];
   tabBarController.tabBarItemsAttributes = tabBarItemsAttributes;
}

第三步:將CYLTabBarController設(shè)置為window的RootViewController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/* *省略部分:   * */
   [self.window setRootViewController:self.tabBarController];
/* *省略部分:   * */
   return YES;
}

第四步(可選):創(chuàng)建自定義的形狀不規(guī)則加號(hào)按鈕

創(chuàng)建一個(gè)繼承于 CYLPlusButton 的類,要求和步驟:

  1. 實(shí)現(xiàn) CYLPlusButtonSubclassing 協(xié)議

  2. 子類將自身類型進(jìn)行注冊(cè),一般可在 applicationapplicationDelegate 方法里面調(diào)用 [YourClass registerSubClass] 或者在子類的 +load 方法中調(diào)用:

+(void)load {
   [super registerSubclass];
}

協(xié)議提供了可選方法:

+ (NSUInteger)indexOfPlusButtonInTabBar;
+ (CGFloat)multiplerInCenterY;
+ (UIViewController *)plusChildViewController;

作用分別是:

+ (NSUInteger)indexOfPlusButtonInTabBar;

用來(lái)自定義加號(hào)按鈕的位置,如果不實(shí)現(xiàn)默認(rèn)居中,但是如果 tabbar 的個(gè)數(shù)是奇數(shù)則必須實(shí)現(xiàn)該方法,否則 CYLTabBarController 會(huì)拋出 exception 來(lái)進(jìn)行提示。

主要適用于如下情景:

enter image description here

Airbnb-app效果:

enter image description here
+ (CGFloat)multiplerInCenterY;

該方法是為了調(diào)整自定義按鈕中心點(diǎn)Y軸方向的位置,建議在按鈕超出了 tabbar 的邊界時(shí)實(shí)現(xiàn)該方法。返回值是自定義按鈕中心點(diǎn)Y軸方向的坐標(biāo)除以 tabbar 的高度,如果不實(shí)現(xiàn),會(huì)自動(dòng)進(jìn)行比對(duì),預(yù)設(shè)一個(gè)較為合適的位置,如果實(shí)現(xiàn)了該方法,預(yù)設(shè)的邏輯將失效。

詳見Demo中的 CYLPlusButtonSubclass 類的實(shí)現(xiàn)。

+ (UIViewController *)plusChildViewController;

詳見: 點(diǎn)擊 PlusButton 跳轉(zhuǎn)到指定 UIViewController

另外,如果加號(hào)按鈕超出了邊界,一般需要手動(dòng)調(diào)用如下代碼取消 tabbar 頂部默認(rèn)的陰影,可在 AppDelegate 類中調(diào)用:

   //去除 TabBar 自帶的頂部陰影
   [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];

如何調(diào)整、自定義 PlusButton 與其它 TabBarItem 的寬度?

CYLTabBarController 規(guī)定:

TabBarItem 寬度 =  ( TabBar 總寬度 -  PlusButton 寬度  ) / (TabBarItem 個(gè)數(shù))

所以想自定義寬度,只需要修改 PlusButton 的寬度即可。

比如你就可以在 Demo中的 CYLPlusButtonSubclass.m 類里:

[button sizeToFit]; 

改為

button.frame = CGRectMake(0.0, 0.0, 250, 100);
button.backgroundColor = [UIColor redColor];

效果如下,

enter image description here

同時(shí)你也可以順便測(cè)試下 CYLTabBarController 的這一個(gè)特性:

即使加號(hào)按鈕超出了tabbar的區(qū)域,超出部分依然能響應(yīng)點(diǎn)擊事件

并且你可以在項(xiàng)目中的任意位置讀取到 PlusButton 的寬度,借助 CYLTabBarController.h 定義的 CYLPlusButtonWidth 這個(gè)extern??蓞⒖?+[CYLTabBarControllerConfig customizeTabBarAppearance:] 里的用法。

補(bǔ)充說明

自定義 TabBar 樣式

如果想更進(jìn)一步的自定義 TabBar 樣式可在 -application:didFinishLaunchingWithOptions: 方法中設(shè)置

/**
*  tabBarItem 的選中和不選中文字屬性、背景圖片
*/
- (void)customizeInterface {
   
   // 普通狀態(tài)下的文字屬性
   NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary];
   normalAttrs[NSForegroundColorAttributeName] = [UIColor grayColor];
   
   // 選中狀態(tài)下的文字屬性
   NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
   selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
   
   // 設(shè)置文字屬性
   UITabBarItem *tabBar = [UITabBarItem appearance];
   [tabBar setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
   [tabBar setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
   
   // 設(shè)置背景圖片
   UITabBar *tabBarAppearance = [UITabBar appearance];
   [tabBarAppearance setBackgroundImage:[UIImage imageNamed:@"tabbar_background"]];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/* *省略部分:   * */
   [self.window makeKeyAndVisible];
   [self customizeInterface];
   return YES;
}

橫豎屏適配

TabBar 橫豎屏適配時(shí),如果你添加了 PlusButton,且適配時(shí)用到了 TabBarItem 的寬度, 不建議使用系統(tǒng)的UIDeviceOrientationDidChangeNotification , 請(qǐng)使用庫(kù)里的 CYLTabBarItemWidthDidChangeNotification 來(lái)更新 TabBar 布局,最典型的場(chǎng)景就是,根據(jù) TabBarItem 在不同橫豎屏狀態(tài)下的寬度變化來(lái)切換選中的TabBarItem 的背景圖片。Demo 里 CYLTabBarControllerConfig.m 給出了這一場(chǎng)景的用法:

CYLTabBarController.h 中提供了 CYLTabBarItemWidth 這一extern常量,并且會(huì)在 TabBarItem 的寬度發(fā)生變化時(shí),及時(shí)更新該值,所以用法就如下所示:

- (void)updateTabBarCustomizationWhenTabBarItemWidthDidUpdate {
   void (^deviceOrientationDidChangeBlock)(NSNotification *) = ^(NSNotification *notification) {
       [self tabBarItemWidthDidUpdate];
   };
   [[NSNotificationCenter defaultCenter] addObserverForName:CYLTabBarItemWidthDidChangeNotification
                                                     object:nil
                                                      queue:[NSOperationQueue mainQueue]
                                                 usingBlock:deviceOrientationDidChangeBlock];
}

- (void)tabBarItemWidthDidUpdate {
   UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
   if ((orientation == UIDeviceOrientationLandscapeLeft) || (orientation == UIDeviceOrientationLandscapeRight)) {
       NSLog(@"Landscape Left or Right !");
   } else if (orientation == UIDeviceOrientationPortrait){
       NSLog(@"Landscape portrait!");
   }
   CGSize selectionIndicatorImageSize = CGSizeMake(CYLTabBarItemWidth, [self cyl_tabBarController].tabBar.bounds.size.height);
   [[self cyl_tabBarController].tabBar setSelectionIndicatorImage:[[self class]
                                                                   imageFromColor:[UIColor yellowColor]
                                                                   forSize:selectionIndicatorImageSize
                                                                   withCornerRadius:0]];
}
enter image description here

訪問初始化好的 CYLTabBarController 對(duì)象

對(duì)于任意 NSObject 對(duì)象:

CYLTabBarController.h 中為 NSObject 提供了分類方法 -cyl_tabBarController ,所以在任意對(duì)象中,一行代碼就可以訪問到一個(gè)初始化好的 CYLTabBarController 對(duì)象,-cyl_tabBarController 的作用你可以這樣理解:與獲取單例對(duì)象的 +shareInstance 方法作用一樣。

接口如下:

// CYLTabBarController.h

@interface NSObject (CYLTabBarController)

/**
* If `self` is kind of `UIViewController`, this method will return the nearest ancestor in the view controller hierarchy that is a tab bar controller. If `self` is not kind of `UIViewController`, it will return the `rootViewController` of the `rootWindow` as long as you have set the `CYLTabBarController` as the  `rootViewController`. Otherwise return nil. (read-only)
*/
@property (nonatomic, readonly) CYLTabBarController *cyl_tabBarController;

@end

用法:

//導(dǎo)入 CYLTabBarController.h
#import "CYLTabBarController.h"

- (void)viewDidLoad {
   [super viewDidLoad];
   CYLTabBarController *tabbarController = [self cyl_tabBarController];
   /*...*/
}

點(diǎn)擊 PlusButton 跳轉(zhuǎn)到指定 UIViewController

提供了一個(gè)協(xié)議方法來(lái)完成本功能:

enter image description here

實(shí)現(xiàn)該方法后,能讓 PlusButton 的點(diǎn)擊效果與跟點(diǎn)擊其他 UITabBarButton 效果一樣,跳轉(zhuǎn)到該方法指定的 UIViewController 。

注意:必須同時(shí)實(shí)現(xiàn) +indexOfPlusButtonInTabBar 來(lái)指定 PlusButton 的位置。

遵循兩個(gè)協(xié)議:

enter image description here

讓TabBarItem僅顯示圖標(biāo),并使圖標(biāo)垂直居中

要想實(shí)現(xiàn)該效果,只需要在設(shè)置 tabBarItemsAttributes該屬性時(shí)不傳 title 即可。

比如:在Demo的基礎(chǔ)上,注釋掉圖中紅框部分:


enter image description here
注釋前 注釋后
enter image description here
enter image description here

可以通過這種方式來(lái)達(dá)到 Airbnb-app 的效果:

enter image description here

如果想手動(dòng)設(shè)置偏移量來(lái)達(dá)到該效果:
可以在 -setViewControllers: 方法前設(shè)置 CYLTabBarControllerimageInsetstitlePositionAdjustment 屬性

這里注意:設(shè)置這兩個(gè)屬性后,TabBar 中所有的 TabBarItem 都將被設(shè)置。并且第一種做法的邏輯將不會(huì)執(zhí)行,也就是說該做法優(yōu)先級(jí)要高于第一種做法。

做法如下:


enter image description here

但是想達(dá)到Airbnb-app的效果只有這個(gè)接口是不行的,還需要自定義下 TabBar 的高度,你需要設(shè)置 CYLTabBarControllertabBarHeight 屬性。你可以在Demo的 CYLTabBarControllerConfig.m 中的 -customizeTabBarAppearance: 方法中設(shè)置。

注:“僅顯示圖標(biāo),并使圖標(biāo)垂直居中”這里所指的“圖標(biāo)”,其所屬的類是私有類: UITabBarSwappableImageView,所以 CYLTabBarController 在相關(guān)的接口命名時(shí)會(huì)包含 SwappableImageView 字樣。

在 Swift 項(xiàng)目中使用 CYLTabBarController

參考: 《從頭開始swift2.1 仿搜材通項(xiàng)目(三) 主流框架Tabbed的搭建》

這里注意,文章的示例代碼有問題,少了設(shè)置 PlusButton 大小的代碼:
這將導(dǎo)致 PlusButton 點(diǎn)擊事件失效,具體修改代碼如下:


enter image description here

源碼實(shí)現(xiàn)原理

參考: 《[Note] CYLTabBarController》

更多文檔信息可查看 CocoaDocs:CYLTabBarController 。

Q-A

Q:為什么放置6個(gè)TabBarItem會(huì)顯示異常?

A:

Apple 規(guī)定:

一個(gè) TabBar 上只能出現(xiàn)最多5個(gè) TabBarItem ,第六個(gè)及更多的將不被顯示。

另外注意,Apple檢測(cè)的是 UITabBarItem 及其子類,所以放置“加號(hào)按鈕”,這是 UIButton 不在“5個(gè)”里面。

最多只能添加5個(gè) TabBarItem ,也就是說加上“加號(hào)按鈕”,一共最多在一個(gè) TabBar 上放置6個(gè)控件。否則第6個(gè)及之后出現(xiàn) TabBarItem 會(huì)被自動(dòng)屏蔽掉。而且就Apple的審核機(jī)制來(lái)說,超過5個(gè)也會(huì)被直接拒絕上架。

Q: 如何實(shí)現(xiàn)添加選中背景色的功能 ,像下面這樣:


screen shot 2015-10-28 at 9 21 56 am
screen shot 2015-10-28 at 9 21 56 am

A:我已經(jīng)在 Demo 中添加了如何實(shí)現(xiàn)該功能的代碼:
詳情見 CYLTabBarControllerConfig 類中下面方法的實(shí)現(xiàn):

/**
*  更多TabBar自定義設(shè)置:比如:tabBarItem 的選中和不選中文字和背景圖片屬性、tabbar 背景圖片屬性
*/
- (void)customizeTabBarAppearance:(CYLTabBarController *)tabBarController;

效果如下:


simulator screen shot 2015 10 28 11 44 32
simulator screen shot 2015 10 28 11 44 32

Q: 當(dāng) ViewController 設(shè)置的 self.titletabBarItemsAttributes 中對(duì)應(yīng)的 title 不一致的時(shí)候,會(huì)出現(xiàn)如圖的錯(cuò)誤,排序不對(duì)了

A:在 v1.0.7 版本中已經(jīng)修復(fù)了該 bug,但是也需要注意:

請(qǐng)勿使用 self.title = @"同城"; 這種方式,請(qǐng)使用 self.navigationItem.title = @"同城";

self.title = @"同城"; 這種方式,如果和 tabBarItemsAttributes 中對(duì)應(yīng)的 title 不一致的時(shí)候可能會(huì)導(dǎo)致如下現(xiàn)象(不算 bug,但看起來(lái)也很奇怪):

enter image description here
enter image description here

規(guī)則如下:


   self.navigationItem.title = @"同城";    //?sets navigation bar title.The right way to set the title of the navigation
   self.tabBarItem.title = @"同城23333";   //?sets tab bar title. Even the `tabBarItem.title` changed, this will be ignored in  tabbar.
   self.title = @"同城1";                  //?sets both of these. Do not do this???? This may cause something strange like this : http://i68.tinypic.com/282l3x4.jpg 

Q : 當(dāng)使用這個(gè)方法時(shí) -[UIViewController cyl_jumpToOtherTabBarControllerItem:(Class)ClassType performSelector:arguments:returnValue:] 會(huì)出現(xiàn)如下的黑邊問題。

enter image description here

A: 這個(gè)是 iOS 系統(tǒng)的BUG,經(jīng)測(cè)試iOS9.3已經(jīng)修復(fù)了,如果在更早起版本中出現(xiàn)了,可以通過下面將 rootWindow 的背景色改為白色來(lái)避免:比如你可以 Appdelegate 類里這樣設(shè)置:

//#import "CYLTabBarController.h"
   [[self cyl_tabBarController] rootWindow].backgroundColor = [UIColor whiteColor];

Q:我現(xiàn)在已經(jīng)做好了一個(gè)比較簡(jiǎn)單的中間凸起的 icon 但是超過了49這個(gè)高度的位置是不能效應(yīng)的 我想請(qǐng)問你的demo哪個(gè)功能是可以使我超出的范圍也可以響應(yīng)的呢?

A: 這個(gè)是自動(dòng)做的,但是 CYLTabBarController 只能保證的是:只要是 UIButton 的 frame 區(qū)域內(nèi)就能響應(yīng)。

請(qǐng)把 button 的背景顏色設(shè)置為顯眼的顏色,比如紅色,比如像下面的plus按鈕,紅色部分是能接收點(diǎn)擊事件的,但是超出了紅色按鈕的,黃色的圖片區(qū)域,依然是無(wú)法響應(yīng)點(diǎn)擊事件的。

enter image description here

這是因?yàn)?,在響?yīng)鏈上,UIControl 能響應(yīng)點(diǎn)擊事件, UIImage 無(wú)法響應(yīng)。

(更多iOS開發(fā)干貨,歡迎關(guān)注 微博@iOS程序犭袁


Posted by 微博@iOS程序犭袁
原創(chuàng)文章,版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
<p align="center"><a target="_blank">

</a></a>

最后編輯于
?著作權(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)容