この記事では、最新のプロジェクトの1つで、このような美しいカスタムプログレスバーを作成する方法を図で説明したいと思います。
タスクは次のように設定されました。
- 写真はデザイナーによって描かれました。
- 進行状況バーはオーバーラップし、UI全体をブロックします。
- NSNotificationCenterの通知によってアイテムを呼び出す必要があります。
- 要素を途中で終了させることができるはずです。
- 送信された通知の数に関係なく、1つの進行状況バーがあるはずです。
実装に興味がある人は猫をお願いします。
まず、シングルトンBSBeautifulProgressBarManagerを作成し、BSBeautifulProgressBarManager.hに書き込みます 。
押して!
#import <Foundation/Foundation.h> #define kShouldShowBeautifulProgressBar @"kShouldShowBeautifulProgressBar" #define kShouldHideBeautifulProgressBar @"kShouldHideBeautifulProgressBar" #define beautifulProgressBarManager [BSBeautifulProgressBarManager sharedManager] @interface BSBeautifulProgressBarManager : NSObject + (BSBeautifulProgressBarManager *)sharedManager; @end
職場では、定義のトリックを使用して、クラス名ごとにシングルトーンを常に使用することをなくしています。 ここでは、[BSBeautifulProgressBarManager sharedManager]の代わりに、単にBSBeautifulProgressBarManagerと書くことができます。 ヘッダーファイルにはもう触れません。
通常、いくつかのConfig.hで通知通知を取り出します。通知を送信するためにマネージャーヘッダーをインポートする必要はありません。 ただし、この例では、マジック定数をシングルトンヘッダーに直接取り除くためのトリックを追加します。
BSBeautifulProgressBarManager.mファイルのシングルトン実装を見てみましょう。
押して!
+ (BSBeautifulProgressBarManager *)sharedManager { static BSBeautifulProgressBarManager *sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedManager = [self new]; [[NSNotificationCenter defaultCenter] addObserver:sharedManager selector:@selector(showProgressBar) name:kShouldShowBeautifulProgressBar object:nil]; [[NSNotificationCenter defaultCenter] addObserver:sharedManager selector:@selector(hideProgressBar) name:kShouldHideBeautifulProgressBar object:nil]; }); return sharedManager; }
これまでのところ特別なことは何も起きていません-通常のスレッドセーフなシングルトン実装です。 このメソッドの唯一の注目すべき点は、NSNotificationCenterで進行状況バー通知を表示/非表示にするサブスクリプションです。
showProgressBarおよびhideProgressBarメソッドの実装に移りましょう。
押して!
- (void)showProgressBar { if (isShown) return; isShown = YES; } - (void)hideProgressBar { if (!isShown) return; isShown = NO; }
これまでのところ、彼らは何もしていません。 ただし、要素の2つの作業条件を既に満たしています。プログレスバーは1つだけで、NSNotificationCenterから呼び出されます。 したがって、実装にプライベート変数を追加します。
押して!
@implementation BSBeautifulProgressBarManager { BOOL isShown; }
私たちのアイデアはこれになります:
- 最初のレイヤーは半透明の黒いUIViewで、UIWindowにオーバーレイします。 したがって、UI全体を再描画します。 このUIViewへのリンクを残して、必要に応じて後で削除します。
- その上に白いUIViewを追加します。これはメインの上部ストリップとして機能します。 リンクも保存します-必要に応じてこのUIViewをきれいに削除する必要があります。
- 灰色の稲妻の静止画像を白いUIViewに追加します。
- オレンジ色のジッパー画像を白いUIViewに追加します。 幅を0に設定します。アニメーションブロックを使用して、この画像を自然なサイズに拡大します。 したがって、美しい視覚効果を実現します。
実装を始めましょう! まず、showProgressBarメソッドを変更します。
押して!
- (void)showProgressBar { if (isShown) return; isShown = YES; [self addGreyView]; [self addWhiteView]; [self addGreyZip]; [self addOrangeZip]; }
すべてが計画通りに進みます-要素を個々のメソッドに追加する機能をカプセル化しました。 これらの方法を見ていきましょう。コメントを少し低くします。
押して!
@implementation BSBeautifulProgressBarManager { BOOL isShown; // 1 UIView *mainView; UIView *whiteView; } <...> - (void)addGreyView { // 2 UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject]; mainView = [[UIView alloc] initWithFrame:window.bounds]; mainView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5]; mainView.alpha = 0.0; [window addSubview:mainView]; // 3 [UIView animateWithDuration:0.3 animations:^{ mainView.alpha = 1.0; }]; } - (void)addWhiteView { // 4 whiteView = [[UIView alloc] initWithFrame:CGRectMake(0, -64, 320, 64)]; whiteView.backgroundColor = [UIColor whiteColor]; [mainView addSubview:whiteView]; // 5 [UIView animateWithDuration:0.3 animations:^{ CGRect frame = whiteView.frame; frame.origin.y = 0; whiteView.frame = frame; }]; } - (void)addGreyZip { // 6 CGRect frame = CGRectMake(0, 39, 320, 14.5); UIImageView *greyImageView = [[UIImageView alloc] initWithFrame:frame]; greyImageView.image = [UIImage imageNamed:@"grey"]; [whiteView addSubview:greyImageView]; } - (void)addOrangeZip { // 7 CGRect frame = CGRectMake(0, 0, 320, 14.5); CGRect frameSmaller = CGRectMake(1, 39, 0, 14.5); // 8 UIView *container = [[UIView alloc] initWithFrame:frameSmaller]; container.clipsToBounds = YES; // 9 UIImageView *redImageView = [[UIImageView alloc] initWithFrame:frame]; redImageView.image = [UIImage imageNamed:@"red"]; [container addSubview:redImageView]; // 10 [whiteView addSubview:container]; // 11 [UIView animateWithDuration:15. animations:^{ CGRect frame = container.frame; frame.size.width = 320; container.frame = frame; }]; }
順番に行きましょう:
- 背景(mainView)と白いビュー(whiteView)にリンクを追加します。 背景の表示と非表示(フェードインとフェードアウト)が必要になります。最初は、白いビューを下げてから美しく上げるのが美しいです。
- 背景を作成します。これは、要素のメインのスーパービューであり、黒で半透明にし、UI全体をカバーするためにアプリケーションウィンドウに配置します。
- 背景に対してフェードインを行い、それをすべての子孫、つまり要素の残りに対してフェードインします。
- 残りの要素に白いビューの背景を作成し、メインビューに配置して、祖先の上端の後ろに隠します。
- 美しく、すべての子孫を下に白いビューをアニメーションで下げます。 ちなみに、子孫は稲妻になります。
- 灰色の稲妻の静止画像を白いビューに追加します-複雑なことはありません。
- オレンジ色の稲妻では、すべてがより複雑になります。 UIViewコンテナとUIImageView稲妻の2つのビューを作成します。 アイデアは次のとおりです。ビュー内に幅0のUIImageViewを追加し、コンテナーを目的のサイズにアニメーション化します。 右のオレンジ色の稲妻に「成長」する一定の効果が得られます。 これを行うには、写真(フレーム)とコンテナ(frameSmaller)の2つのフレームを準備します。
- コンテナを作成し、その子孫が越えないようにしてください。
- コンテナにオレンジ色の稲妻の写真を追加します-超自然的ではありません。
- 白いビューにコンテナを追加します。
- コンテナ拡張をアニメーション化します。
いいね! これで、必要に応じて進行状況バーを表示できます。 進行状況バーを非表示にするメソッドの実装に移りましょう。
押して!
- (void)hideProgressBar { if (!isShown) return; isShown = NO; [self hideGreyView]; [self hideWhiteView]; [self finish]; }
考え方は単純です:メインビュー(黒半透明または単純にグレー)を非表示にし、この時点ですべての内側の白いビューを削除し、オレンジ色の稲妻をすぐに最後に表示します-最後まで展開されていない場合は、ユーザーに表示するために、アクションが完了したと言います。
実装に取りかかりましょう、以下のコメント:
押して!
- (void)hideGreyView { // 1 [UIView animateWithDuration:0.3 animations:^{ mainView.alpha = 0.0; } completion:^(BOOL finished){ [mainView removeFromSuperview]; }]; } - (void)hideWhiteView { // 2 [UIView animateWithDuration:0.3 animations:^{ CGRect frame = whiteView.frame; frame.origin.y = -64; whiteView.frame = frame; }]; } - (void)finish { // 3 CGRect frame = CGRectMake(0, 39, 320, 14.5); UIImageView *greyImageView = [[UIImageView alloc] initWithFrame:frame]; greyImageView.backgroundColor = [UIColor whiteColor]; greyImageView.image = [UIImage imageNamed:@"grey"]; [whiteView addSubview:greyImageView]; // 4 frame = CGRectMake(1, 39, 320, 14.5); UIImageView *redImageView = [[UIImageView alloc] initWithFrame:frame]; redImageView.image = [UIImage imageNamed:@"red"]; [whiteView addSubview:redImageView]; }
すべてが簡単です:
- メインビューとそのすべての内臓の祖先から削除するフェードアウトをそれぞれ行います。
- 白いビューをすべての内部でクリーンアップします
- 最も残酷で「抜け穴」の方法-新しい灰色の稲妻を上に置く
- 新しいオレンジのジッパーを上に置きます-これにより、下から隠された稲妻が消えたような感覚が生まれます
ところで、必要な写真は次のとおりです。
押して!
以上です! あなたは、実際に機能するソーシャルネットワークの一部を学びました。 実際、彼らは本番からコードに突入しました。 必要な通知を送信することにより、カスタムの美しいプログレスバーを呼び出すことができます。
おわりに
最後まで読んでくれてありがとう! あなたの質問に喜んでお答えします。 誤字や誤りを見つけた場合は、お気軽にHabracenterにご連絡ください!
次の記事で見たいものを書いてください。