Advertisement
  1. Code
  2. Mobile Development

Animasi komponen dengan UIKit Dynamic: Bagian 1

Scroll to top
Read Time: 24 min

Indonesian (Bahasa Indonesia) translation by Regi Faqihudin (you can also view the original English article)

Pengenalan

Dalam tutorial ini, saya akan menunjukkan kepada Anda sebuah tambahan baru ke iOS SDK yang diperkenalkan di iOS 7, UIKit dynamic dan aku akan menunjukkan Anda bagaimana hal itu dapat digunakan untuk menciptakan efek animasi menarik, eye-catching.

Tujuan dari antarmuka adalah untuk memungkinkan pengembang untuk menambahkan realisme ke aplikasi mereka dengan cara yang mudah dan langsung. Dalam tutorial ini, kita akan melihat beberapa contoh yang menggambarkan hal ini.

Dalam bagian pertama dari tutorial ini, saya akan menunjukkan bagaimana untuk membuat menu animasi dan dalam bagian kedua kami akan berfokus pada menciptakan view alert animasi yang disesuaikan. Kita akan menciptakan menu dan alert view sebagai standalone komponen untuk memaksimalkan usabilitas.

1. UIKit Dynamic Essentials

Sebelum kita mulai menulis kode, diperlukan untuk melihat esensi UIKit Dynamic. UIKit Dynamic merupakan bagian dari Framework UIKit, yang berarti bahwa Anda tidak perlu menambahkan Framework tambahan setiap kali proyek Anda menggunakannya.

Menyediakan pengembang dengan antarmuka untuk menambahkan efek realistis untuk view layer aplikasi Anda. Sangat penting untuk menyebutkan bahwa UIKit Dynamic membuat menggunakan Physic Engine untuk melakukan tugasnya. Hal ini memungkinkan pengembang untuk fokus pada fungsi yang mereka ingin tambah ke aplikasi mereka bukannya implementasi. Pemahaman dasar matematika dan fisika yang Anda butuhkan untuk memulai dengan UIKit Dynamic.

Komponen utama dari antarmuka UIKi Dynamic adalah class UIDynamicAnimator, yang juga dikenal sebagai dynamic animator class ini bertanggung jawab untuk melakukan animasi menggunakan phyisc engine di belakang layar. Meskipun  dynamic animator adalah jantung antarmuka UIKit Dynamic, itu tidak dapat digunakan sendiri.

Untuk bekerja, perilaku tertentu harus ditambahkan ke dynamic animator. Perilaku ini adalah koleksi physic yang memaksa mendefinisikan animasi yang dihasilkan dengan menambahkan satu atau lebih perilaku. Pemrograman berbicara, perilakudinamis class antarmuka UIKit Dynamic dan perilaku masing-masing memiliki atribut tertentu yang dapat dimodifikasi untuk mempengaruhi animasi.

Class dasar perilaku adalah class UIDynamicBehavior. Meskipun Anda bebas untuk membuat perilaku kustom Anda sendiri, UIKit Dynamic datang dengan sejumlah easy-to-uaw subclass yang meniru perilaku umum, seperti gravitasi dan tabrakan.

  • UIGravityBehavior: Subclass UIDynamicBehavior ini menambah gravitasi item. Sebagai akibatnya, item bergerak ke arah tertentu didefinisikan oleh perilaku gravitasi.
  • UICollisionBehavior: Class ini mendefinisikan bagaimana dua item berbenturan dengan satu sama lain atau bagaimana item bertabrakan dengan batas standar, terlihat atau tidak terlihat.
  • UIPushBehavior: Seperti namanya menunjukkan, perilaku ini memberikan item dorongan, itu mempercepat item. dorongan dapat terus-menerus atau seketika. Perilaku continuous dorongan secara bertahap berlaku kekuatan push sementara seketika mendorong perilaku berlaku angkatan saat perilaku ditambahkan.
  • UISnapBehavior: Perilaku snap mendefinisikan bagaimana item terkunci ke item lain atau titik dalam ruang. Perilaku snap disesuaikan dalam beberapa cara. Misalnya, item dapat snap ke titik tanpa bounciness apapun atau goncang untuk beberapa saat sebelum datang menjadi berhenti.
  • UIAttachmentBehavior: Perilaku lampiran mendefinisikan bagaimana dua item dinamis terhubung ke satu sama lain atau bagaimana item dinamis yang terhubung ke titik anchor.

Ini adalah perilaku dinamis yang paling penting saat ini disediakan oleh antarmuka UIKit Dynamic. Dalam rangka untuk perilaku ini untuk melakukan pekerjaan mereka, mereka perlu diinisialisasi, dikonfigurasi, dan ditambahkan ke objek dynamic animator, yang kita bahas sebelumnya.

Menggabungkan perilaku ini mungkin selama mereka tidak menyebabkan konflik apapun. Juga mencatat bahwa beberapa perilaku hanya dapat ditambahkan sekali ke objek dynamic animator. Sebagai contoh, menambahkan dua instance class UIGravityBehavior ke dynamic animator akan mengakibatkan exception.

Perilaku yang selalu diterapkan ke item dinamis. Item dinamis adalah objek apapun yang sesuai dengan protokol UIDynamicItem. Hal yang hebat adalah bahwa UIView dan UICollectionViewLayoutAttributes class sudah sesuai dengan protokol ini. Ini berarti bahwa setiap view dalam aplikasi Anda dapat memanfaatkan UIKit Dynamic.

Ada satu subclass UIDynamicBehavior lain yang layak disebut, UIDynamicItemBehavior. Daripada mendefinisikan perilaku tertentu, menawarkan konfigurasi dasar animasi yang dinamis yang dapat diterapkan ke item yang dinamis. Ini memiliki sejumlah properti untuk menentukan perilaku:

  1. elasticity: properti ini mendefinisikan elastisitas tabrakan antara dinamis item atau item yang dinamis dan batas. Nilai berkisar dari 0.0 sampai 1.0 dengan yang terakhir menjadi sangat elastis tabrakan.
  2. density: properti ini mendefinisikan massa item dinamis dengan nilai yang tinggi yang mengakibatkan benda berat. Hal ini dapat berguna jika Anda tidak ingin item yang dinamis dipindahkan ketika item lain bertabrakan dengan itu.
  3. resistance: nama properti berbicara untuk dirinya sendiri. Properti ini mendefinisikan redaman kecepatan item dinamis.
  4. angularResistance: ini serupa dengan resistance properti, tapi properti angularResistance mendefinisikan redaman kecepatan sudut.
  5. friction: properti ini mendefinisikan gesekan atau perlawanan dari dua item dinamis yang geser terhadap satu sama lain.
  6. allowsRotation: ini hanya menentukan jika item dinamis yang diperbolehkan untuk memutar atau tidak.

Menggabungkan perilaku dinamis dapat memberikan hasil yang spektakuler. Dalam tutorial ini, kita akan menggunakan sebagian besar perilaku yang tercantum di atas.

Saya mendorong Anda untuk mengunjungi Apple dokumentasi resmi dan membaca lebih lanjut tentang kelas kunci UIKit Dynamic. Juga, setelah menyelesaikan tutorial ini, sangat berguna untuk bermain-main dengan hasil untuk mendapatkan pemahaman yang lebih baik dari konsep-konsep dan berbagai macam kebiasaan yang didefinisikan oleh UIKit Dynamic.

2. aplikasi Overview

Saya telah menyebutkan dalam pendahuluan bahwa kita akan menciptakan dua komponen reusable yang akan memanfaatkan UIKit Dynamicc. Dalam tutorial ini, kita akan membuat menu animasi kustom. Lihatlah hasil di bawah ini.

Komponen ini adalah sebuah objek UIView yang slide in dan out dari layar. Untuk membuat menu muncul dan menghilang, swife sederhana gesture digunakan. Item menu tercantum dalam tampilan polos tabel. Animasi yang Anda lihat dalam gambar di atas dicapai dengan menggabungkan sejumlah perilaku dinamis.

3. menciptakan proyek

Mulai dengan meluncurkan Xcode dan membuat proyek baru. Pilih Single View Application dalam Application kategori bagian iOS aplikasi. Klik Next untuk melanjutkan.

Namai proyek DynamicsDemo dan pastikan bahwa Devices diatur untuk iPhone. Untuk tutorial ini, saya sudah meninggalkan bidang Class Prefix kosong, tetapi jangan ragu untuk memasukkan Class Prefix Anda sendiri. Klik Next, memberitahu Xcode dimana Anda ingin menyimpan proyek, dan tekan Create.

Download source file tutorial ini dan menambahkan gambar dari proyek Xcode untuk proyek Anda dalam folder Images.xcassets Project Navigator.

(Gambar hak cipta: icons8)

4. memahami Menu

Sebelum kita mulai mengimplementasikan komponen menu, penting untuk mengambil melihat lebih dekat bagaimana itu harus beroperasi. Seperti tyang elah saya sebutkan, menu harus memperlihatkan dirinya dengan sliding ke tampilan dari kanan ke kiri dan menyembunyikan diri dengan sliding keluar view dari kiri ke kanan.

Menampilkan dan menyembunyikan menu dipicu oleh gerakan swipe. UIKit Dynamic akan bertanggung jawab atas perilaku atau animasi menu. Perilaku yang akan kita gunakan adalah:

  1. Gravitasi behavior: perilaku gravitasi akan membuat menu bergerak dalam arah yang benar, kiri atau kanan. Tanpa perilaku gravitasi, menu tidak akan berbuat banyak.
  2. Collision behavior: perilaku tabrakan sama pentingnya. Tanpa itu, menu tidak berhenti bergerak setelah gravitasi diterapkan untuk itu. Batas terlihat akan memicu tabrakan dan membuat menu berhenti dimana kita ingin berhenti.
  3. Push behavior: Meskipun perilaku gravitasi dan tabrakan dapat menghidupkan menu masuk dan keluar, kami akan memberikan tambahan mendorong atau percepatan menggunakan mendorong perilaku. Ini akan membuat animasi snappier.
  4. Dynamic item behavior: kami juga akan menambahkan sebuah perilaku dinamis item untuk menentukan elastisitas menu. Hal ini akan mengakibatkan tabrakan goyang.

Daripada instantiating perilaku di atas setiap kali mereka perlu mengambil efek, kita akan menginisialisasi mereka sekali. Kami menerapkan dan mengkonfigurasi perilaku ketika kita membutuhkan mereka, yang akan tergantung pada posisi menu dan arah yang dibutuhkan untuk bergerak.

5. properti, struktur, dan inisialisasi

Langkah 1: Membuat Class

Mari kita mulai dengan menambahkan class baru untuk proyek. Tekan Command-N, Pilih Objective-C class dari daftar template di iOS > Cocoa Touch bagian. Klik Next untuk melanjutkan.

Namai kelas baru MenuComponent dan pastikan class mewarisi dari NSObject. Klik Next, memberitahu Xcode mana Anda ingin menyimpan file class, dan tekan Create.

Langkah 2: Mendeklarasikan properti

Buka MenuComponent.h dan mendefinisikan penghitungan yang akan mewakili arah menu. Arah dapat kiri-ke-kanan atau kanan-ke-kiri. Tambahkan potongan kode berikut di bawah ini pernyataan import.

1
typedef enum MenuDirectionOptionTypes{
2
    menuDirectionLeftToRight,
3
    menuDirectionRightToLeft
4
} MenuDirectionOptions;

Buka MenuComponent.m, menambahkan ekstensi class, dan menyatakan properti berikut:

1
@interface MenuComponent()
2
3
@property (nonatomic, strong) UIView *menuView;
4
@property (nonatomic, strong) UIView *backgroundView;
5
@property (nonatomic, strong) UIView *targetView;
6
@property (nonatomic, strong) UITableView *optionsTableView;
7
@property (nonatomic, strong) NSArray *menuOptions;
8
@property (nonatomic, strong) NSArray *menuOptionImages;
9
@property (nonatomic, strong) UIDynamicAnimator *animator;
10
@property (nonatomic) MenuDirectionOptions menuDirection;
11
@property (nonatomic) CGRect menuFrame;
12
@property (nonatomic) CGRect menuInitialFrame;
13
@property (nonatomic) BOOL isMenuShown;
14
15
@end
  • menuView: ini adalah view objek menu yang akan digerakan masuk dan keluar dari view. table view akan subview view ini.
  • backgroundView: latar belakang view adalah view semi-transparan yang akan mencegah pengguna dari menekan apa pun kecuali pada tampilan menu.
  • targetView: ini adalah superview yang menu dan latar belakang view yang akan ditambahkan.
  • optionsTableView: ini adalah table view yang akan menjadi daftar pilihan menu.
  • menuOptions: array akan berisi pilihan menu yang akan menampilkan table view.
  • menuOptionImages: array akan berisi nama file gambar yang di sebelah kiri dari setiap table view cell.
  • animator: ini adalah instance UIDynamicAnimator yang akan menghidupkan menu.
  • menuDirection: properti ini adalah jenis MenuDirectionOptions dan menentukan arah kemana menu akan bergerak.
  • menuFrame: ini adalah frame menu.
  • menuInitialFrame: dan ini adalah frame awal menu.
  • isMenuShown: sebuah flag yang menunjukkan apakah menu ditampilkan atau tidak.

Selain private properti ini, kita juga perlu untuk menyatakan beberapa properti public. Kembali ke MenuComponent.h dan menambahkan potongan kode berikut:

1
@interface MenuComponent : NSObject
2
3
@property (nonatomic, strong) UIColor *menuBackgroundColor;
4
@property (nonatomic, strong) NSMutableDictionary *tableSettings;
5
@property (nonatomic) CGFloat optionCellHeight;
6
@property (nonatomic) CGFloat acceleration;
7
8
@end
  • menuBackgroundColor: properti ini digunakan untuk mengatur warna latar belakang menu's.
  • tableSettings: ini adalah dictionary yang saya sebutkan di bagian sebelumnya. Itu mari kita akan mengkonfigurasi table view dengan menetapkan sejumlah pilihan.
  • optionCellHeight: ini adalah atribut table view hanya yang tidak bisa diatur menggunakan dictionary tableSettings. Ini menentukan ketinggian baris table view cell.
  • acceleration: properti ini menentukan besarnya mendorong perilaku, dengan kata lain, jumlah Angkatan yang diterapkan pada tampilan menu ketika itu adalah menswipe ke dalam dan keluar dari view.

Langkah 3: Menerapkan metode inisialisasi

Dalam langkah ini, kami menyatakan initializer kustom di mana kita mengatur:

  • akhir frame pada tampilan menu, yaitu frame ketika animasi selesai dan menu terlihat
  • target view yang pada menu view akan ditambahkan sebagai subview
  • array pilihan dan gambar yang ditampilkan oleh table view
  • Arah animasi bila menu ditampilkan

Interface initializer kustom ditunjukkan di bawah. Tambahkan ke interface publik class MenuComponent.

1
- (id)initMenuWithFrame:(CGRect)frame targetView:(UIView *)targetView direction:(MenuDirectionOptions)direction options:(NSArray *)options optionImages:(NSArray *)optionImages;

Mari kita lihat pada pelaksanaan initializer kustom. Tambahkan kode snippet berikut ke file implementasi class MenuComponent. Implementasi cukup sederhana seperti yang Anda lihat di bawah ini.

1
- (id)initMenuWithFrame:(CGRect)frame targetView:(UIView *)targetView direction:(MenuDirectionOptions)direction options:(NSArray *)options optionImages:(NSArray *)optionImages {
2
    if (self = [super init]) {
3
        self.menuFrame = frame;
4
        self.targetView = targetView;
5
        self.menuDirection = direction;
6
        self.menuOptions = options;
7
        self.menuOptionImages = optionImages;
8
    }
9
    
10
    return self;
11
}

6. mengatur segala sesuatu

Ada sejumlah properti yang perlu diinisialisasi dan saya pikir itu karena itu ide yang baik untuk kelompok mereka bersama-sama dalam beberapa metode private. Menavigasi ke ekstensi class MenuComponent dan nyatakan metode berikut:

1
@interface MenuComponent()
2
3
...
4
5
- (void)setupMenuView;
6
- (void)setupBackgroundView;
7
- (void)setupOptionsTableView;
8
- (void)setInitialTableViewSettings;
9
- (void)setupSwipeGestureRecognizer;
10
11
@end

setupMenuView

Di setupMenuView, kami setup menu view. Karena menu awalnya butuh untuk keluar dari daerah layar yang terlihat, kita mulai dengan menghitung frame awal dalam menu. Kami kemudian menginisialisasi pada menu vuew dengan frame awal, mengatur warna latar belakang, dan menambahkan subview ke sasaran atau parent view.

1
- (void)setupMenuView {
2
    if (self.menuDirection == menuDirectionLeftToRight) {
3
        self.menuInitialFrame = CGRectMake(-self.menuFrame.size.width,
4
                                           self.menuFrame.origin.y,
5
                                           self.menuFrame.size.width,
6
                                           self.menuFrame.size.height);
7
    }
8
    else{
9
        self.menuInitialFrame = CGRectMake(self.targetView.frame.size.width,
10
                                           self.menuFrame.origin.y,
11
                                           self.menuFrame.size.width,
12
                                           self.menuFrame.size.height);
13
    }
14
    
15
    self.menuView = [[UIView alloc] initWithFrame:self.menuInitialFrame];
16
    [self.menuView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.47 blue:0.39 alpha:1.0]];
17
    [self.targetView addSubview:self.menuView];
18
}

setupBackgroundView

Di setupBackgroundView, kami sestup latar belakang view. Perhatikan bahwa nilai alpha latar belakang view awalnya diatur ke 0.0. Kami memperbarui nilai ini saat menu muncul.

1
- (void)setupBackgroundView {
2
    self.backgroundView = [[UIView alloc] initWithFrame:self.targetView.frame];
3
    [self.backgroundView setBackgroundColor:[UIColor grayColor]];
4
    [self.backgroundView setAlpha:0.0];
5
    [self.targetView addSubview:self.backgroundView];
6
}

setupOptionsTableView

Di setupOptionsTableView, kami mulai dengan inisialisasi tabel dengan menerapkan initWithFrame: di mana pada tampilan menu size yang digunakan untuk ukurang table view. Instance MenuComponent ditetapkan sebagai sumber data table view dan delegasi.

1
- (void)setupOptionsTableView {
2
    self.optionsTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.menuFrame.size.width, self.menuFrame.size.height) style:UITableViewStylePlain];
3
    [self.optionsTableView setBackgroundColor:[UIColor clearColor]];
4
    [self.optionsTableView setScrollEnabled:NO];
5
    [self.optionsTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
6
    [self.menuView addSubview:self.optionsTableView];
7
    
8
    [self.optionsTableView setDelegate:self];
9
    [self.optionsTableView setDataSource:self];
10
}

Dengan menetapkan Instance MenuComponent sebagai sumber data table view dan delegasi, kompilator memberitahu kita bahwa class MenuComponent tidak mematuhi protokol UITableViewDataSource dan UITableViewDelegate. Mari kita memperbaiki hal ini dengan memperbarui file header class MenuComponent seperti yang ditunjukkan di bawah ini.

1
@interface MenuComponent : NSObject <UITableViewDataSource, UITableViewDelegate>

setupInitialTableViewSettings

Di setupInitialTableViewSettings, kami menginisialisasi dan mengisi dictionary tableSettings yang kita nyatakan sebelumnya dalam class public interface.

1
- (void)setInitialTableViewSettings {
2
    self.tableSettings = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
3
                          [UIFont fontWithName:@"American Typewriter" size:15.0], @"font",
4
                          [NSNumber numberWithInt:NSTextAlignmentLeft], @"textAlignment",
5
                          [UIColor whiteColor], @"textColor",
6
                          [NSNumber numberWithInt:UITableViewCellSelectionStyleGray], @"selectionStyle",
7
                          nil];
8
}

setupSwipGestureRecognizer

Di setupSwipeGestureRecognizer, kami menginisialisasi dan mengkonfigurasi recognizer gesture swipe yang digunakan untuk menyembunyikan menu view.

1
- (void)setupSwipeGestureRecognizer {
2
    UISwipeGestureRecognizer *hideMenuGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideMenuWithGesture:)];
3
    if (self.menuDirection == menuDirectionLeftToRight) {
4
        hideMenuGesture.direction = UISwipeGestureRecognizerDirectionLeft;
5
    }
6
    else{
7
        hideMenuGesture.direction = UISwipeGestureRecognizerDirectionRight;
8
    }
9
    [self.menuView addGestureRecognizer:hideMenuGesture];
10
}

Dua hal yang harus diperhatikan. Pertama, arah gerakan swipe tergantung pada nilai properti menuDirection. Kedua, hideMenuWithGesture: metode adalah metode private yang dipanggil setiap kali recognizer gerakan mendeteksi gerakan swipe. Kami akan menerapkan metode ini nanti, tetapi, untuk menyingkirkan peringatan compiler, nyatakan metode dalam class private ekstensi class MenuComponent seperti yang ditunjukkan di bawah ini.

1
@interface MenuComponent()
2
3
...
4
5
- (void)hideMenuWithGesture:(UISwipeGestureRecognizer *)gesture;
6
7
@end

Mari kita mengambil keuntungan dari pekerjaan yang baru kita lakukan dengan menerapkan metode helper dalam metode inisialisasi seperti ditunjukkan di bawah.

1
- (id)initMenuWithFrame:(CGRect)frame targetView:(UIView *)targetView direction:(MenuDirectionOptions)direction options:(NSArray *)options optionImages:(NSArray *)optionImages {
2
    if (self = [super init]) {
3
        ...
4
        
5
        // Setup the background view.

6
        [self setupBackgroundView];
7
        
8
        // Setup the menu view.

9
        [self setupMenuView];
10
        
11
        // Setup the options table view.

12
        [self setupOptionsTableView];
13
        
14
        // Set the initial table view settings.

15
        [self setInitialTableViewSettings];
16
        
17
        // Setup the swipe gesture recognizer.

18
        [self setupSwipeGestureRecognizer];
19
    }
20
    
21
    return self;
22
}

Perhatikan bahwa latar belakang view set up sebelum view menu untuk memastikan bahwa latar belakang view terletak di bawah menu view.

Akhirnya, menginisialisasi properti yang tersisa setelah menerapkan metode helper seperti ditunjukkan di bawah.

1
- (id)initMenuWithFrame:(CGRect)frame targetView:(UIView *)targetView direction:(MenuDirectionOptions)direction options:(NSArray *)options optionImages:(NSArray *)optionImages {
2
    if (self = [super init]) {
3
        ...
4
        
5
        // Initialize the animator.

6
        self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.targetView];
7
        
8
        // Set the initial height for each cell row.

9
        self.optionCellHeight = 50.0;
10
        
11
        // Set the initial acceleration value (push magnitude).

12
        self.acceleration = 15.0;
13
        
14
        // Indicate that initially the menu is not shown.

15
        self.isMenuShown = NO;
16
    }
17
    
18
    return self;
19
}

7. Dynamic Behavior

Setiap kali pada menu view muncul atau menghilang, kami menggunakan dynamic behavior yang sama. Kami karena itu akan menggunakan kembali dynamic behavior. Satu-satunya hal yang berbeda adalah arah menu selama animasi.

Kita akan membuat salah satu metode di mana kita akan menginisialisasi dan menerapkan dynamic behavior yang diperlukan dan kami akan memanggil metode ini setiap kali menu state harus berubah. Mulai dengan memperbarui class privatd ekstensi dengan metode toggleMenu.

1
@interface MenuComponent()
2
3
...
4
5
- (void)toggleMenu;
6
7
@end

Aku sudah disebutkan bahwa dynamic behavior yang akan digunakan untuk menghidupkan menu adalah gravitasi, tabrakan, dan mendorong. Setiap perilaku yang memiliki satu atau lebih properti itu, apabila diubah, menentukan arah animasi.

  • Perilaku gravitasi memiliki properti direction, struktur CGVector yang menentukan arah gravitasi. Misalnya, dengan menetapkan properti direction ke {1.0, 0,0} perilaku gravitasi menarik ke kanan sedangkan nilai {0.0, 1.0} menghasilkan gaya yang menarik ke bagian bawah.
  • Perilaku tabrakan bekerja di antara dua item dinamis atau di antara item yang dinamis dan batas. Dalam contoh kita, kita perlu batas terlihat didefinisikan oleh dua poin yang berhenti pada menu view.
  • perilaku mendorong memiliki properti magnitude mendefinisikan percepatan berlaku untuk item yang dinamis. Nilai ini juga menentukan arah dorongan.

Dalam metode toggleMenu, kita pertama menghitung nilai-nilai dari properti tersebut. Kami kemudian membuat dan mengkonfigurasi perilaku dinamis, dan menambahkannya ke objek dynamic animator.

Hal ini penting untuk menekankan bahwa nilai-nilai isMenuShown, menunjukkan apakah menu saat ini ditampilkan atau tidak, dan menuDirection, menentukan arah animasi, menentukan nilai dari properti tersebut.

Objek animator memiliki sebuah array yang berisi setiap dynamic behavior yang telah ditambahkan ke itu. Setiap kali toggleMenu metode ini dipanggil, dynamic behavior yang ada perlu dihapus oleh mengbersihkan array, karena beberapa dynamic behavior tidak dapat ditambahkan dua kali untuk perilaku dinamis, seperti perilaku gravitasi.

Mari kita mulai menerapkan metode toggleMenu.

1
- (void)toggleMenu{
2
    // Remove any previous behaviors added to the animator.

3
    [self.animator removeAllBehaviors];
4
    
5
    // The following variables will define the direction of the menu view animation.

6
    
7
    // This variable indicates the gravity direction.

8
    CGFloat gravityDirectionX;
9
    
10
    // These two points specify an invisible boundary where the menu view should collide.

11
    // The boundary must be always to the side of the gravity direction so as the menu view

12
    // can stop moving.

13
    CGPoint collisionPointFrom, collisionPointTo;
14
    
15
    // The higher the push magnitude value, the greater the acceleration of the menu view.

16
    // If that value is set to 0.0, then only the gravity force will be applied to the

17
    // menu view.

18
    CGFloat pushMagnitude = self.acceleration;
19
}

gravityDirectionX, collisionPointFrom, collisionPointTo, dan pushMagnitude variabel akan menyimpan nilai-nilai yang ditetapkan untuk dynamic behavior kemudian. Mari kita menetapkan nilai-nilai mereka, tergantung pada state menu's dan arah animasi.

1
- (void)toggleMenu{
2
    ...
3
    
4
    // Check if the menu is shown or not.

5
    if (!self.isMenuShown) {
6
        // If the menu view is hidden and it's about to be shown, then specify each variable

7
        // value depending on the animation direction.

8
        if (self.menuDirection == menuDirectionLeftToRight) {
9
            // The value 1.0 means that gravity "moves" the view towards the right side.

10
            gravityDirectionX = 1.0;
11
            
12
            // The From and To points define an invisible boundary, where the X-origin point

13
            // equals to the desired X-origin point that the menu view should collide, and the

14
            // Y-origin points specify the highest and lowest point of the boundary.

15
            
16
            // If the menu view is being shown from left to right, then the collision boundary

17
            // should be defined so as to be at the right of the initial menu view position.

18
            collisionPointFrom = CGPointMake(self.menuFrame.size.width, self.menuFrame.origin.y);
19
            collisionPointTo = CGPointMake(self.menuFrame.size.width, self.menuFrame.size.height);
20
        }
21
        else{
22
            // The value -1.0 means that gravity "pulls" the view towards the left side.

23
            gravityDirectionX = -1.0;
24
            
25
            // If the menu view is being shown from right to left, then the collision boundary

26
            // should be defined so as to be at the left of the initial menu view position.

27
            collisionPointFrom = CGPointMake(self.targetView.frame.size.width - self.menuFrame.size.width, self.menuFrame.origin.y);
28
            collisionPointTo = CGPointMake(self.targetView.frame.size.width - self.menuFrame.size.width, self.menuFrame.size.height);
29
            
30
            // Set to the pushMagnitude variable the opposite value.

31
            pushMagnitude = (-1) * pushMagnitude;
32
        }
33
        
34
        // Make the background view semi-transparent.

35
        [self.backgroundView setAlpha:0.25];
36
    }
37
    else{
38
        // In case the menu is about to be hidden, then the exact opposite values should be

39
        // set to all variables for succeeding the opposite animation.

40
        
41
        if (self.menuDirection == menuDirectionLeftToRight) {
42
            gravityDirectionX = -1.0;
43
            collisionPointFrom = CGPointMake(-self.menuFrame.size.width, self.menuFrame.origin.y);
44
            collisionPointTo = CGPointMake(-self.menuFrame.size.width, self.menuFrame.size.height);
45
            
46
            // Set to the pushMagnitude variable the opposite value.

47
            pushMagnitude = (-1) * pushMagnitude;
48
        }
49
        else{
50
            gravityDirectionX = 1.0;
51
            collisionPointFrom = CGPointMake(self.targetView.frame.size.width + self.menuFrame.size.width, self.menuFrame.origin.y);
52
            collisionPointTo = CGPointMake(self.targetView.frame.size.width + self.menuFrame.size.width, self.menuFrame.size.height);
53
        }
54
        
55
        // Make the background view fully transparent.

56
        [self.backgroundView setAlpha:0.0];
57
    }
58
}

Snipet kode di atas cukup sederhana untuk dipahami, meskipun ukurannya. Komentar dalam kode akan membantu Anda memahami apa yang sedang terjadi. Perhatikan bahwa latar belakang view alpha nilai ditentukan oleh Apakah menu akan ditampilkan atau disembunyikan.

Saatnya untuk menambahkan dynamic behavior. Mari kita mulai dengan perilaku gravitasi.

1
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.menuView]];
2
[gravityBehavior setGravityDirection:CGVectorMake(gravityDirectionX, 0.0)];
3
[self.animator addBehavior:gravityBehavior];

Kami menggunakan variabel gravityDirectionX untuk mengatur gravity's gravityDirection properti.

1
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.menuView]];
2
[collisionBehavior addBoundaryWithIdentifier:@"collisionBoundary"
3
                                       fromPoint:collisionPointFrom
4
                                         toPoint:collisionPointTo];
5
[self.animator addBehavior:collisionBehavior];

Anda mungkin telah memperhatikan bahwa metode inisialisasi perilaku gravitasi dan tabrakan menerima array yang berisi item yang dinamis yang perilaku akan diterapkan. Dalam contoh kita, ada hanya pada menu view.

Sebelum kita menambahkan perilaku mendorong untuk ke dynamic behavior, mari kita pertama membuat dynamic item behavior, yang merupakan, Sederhananya, behavior tujuan umum yang kita akan gunakan untuk menetapkan elasticity tabrakan. Semakin besar nilai elasticity, semakin besar bounciness tumbukan antara view dan batas yang terlihat. Kisaran nilai-nilai yang diterima dari 0.0 sampai 1.0.

1
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.menuView]];
2
[itemBehavior setElasticity:0.35];
3
[self.animator addBehavior:itemBehavior];

Kami bisa mengatur perilaku atribut menggunakan itemBehavior objek, seperti resistance atau friction. Anda dapat bermain-main dengan sifat-sifat ini kemudian jika Anda ingin.

Mari kita sekarang menambahkan perilaku mendorong yang akan mempercepat menu.

1
UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.menuView] mode:UIPushBehaviorModeInstantaneous];
2
[pushBehavior setMagnitude:pushMagnitude];
3
[self.animator addBehavior:pushBehavior];

Dengan mengatur mode ke UIPushBehaviorModeInstantaneous kekuatan perilaku mendorong diterapkan sekaligus bukan secara bertahap. dynamic behavior sekarang telah ditambahkan untuk dynamic animator, yang berarti saatnya untuk membuat menu view muncul dan menghilang.

8. menampilkan dan menyembunyikan Menu

Langkah 1: showMenu

Untuk menampilkan dan menyembunyikan menu, kita harus memanggil metode private toggleMenu. Menu akan muncul ketika swipe gesture terdeteksi oleh target view ke arah swipe. Mari kita mulai dengan menyatakan public method yang kita dapat panggil untuk menampilkan menu. Buka ViewController.h dan menyatakan metode showMenu seperti yang ditunjukkan di bawah ini.

1
@interface MenuComponent : NSObject <UITableViewDataSource, UITableViewDelegate>
2
3
...
4
5
- (void)showMenu;
6
7
@end

Implementasi ini sangat sederhana, karena semua yang kita lakukan adalah memanggil metode toggleMenu. Perhatikan bahwa kami memperbarui isMenuShown untuk mencerminkan state baru menu.

1
- (void)showMenu {
2
    if (!self.isMenuShown) {
3
        [self toggleMenu];
4
        
5
        self.isMenuShown = YES;
6
    }
7
}

Langkah 2: Menampilkan Menu

Mari kita mulai menggunakan MenuComponent class di view controller. Buka ViewController.m dan menambahkan pernyataan import di bagian atas.

1
#import "MenuComponent.h"

Dalam ViewController's class private ekstensi, yatakan properti menuComponent jenis MenuComponent untuk menu.

1
@interface ViewController ()
2
3
@property (nonatomic, strong) MenuComponent *menuComponent;
4
5
@end

Sebelum kita menginisialisasi menu, mari kita membuat recognizer gerakan yang akan mendeteksi gerakan swipe untuk menampilkan dan menyembunyikan menu. Kami melakukan ini dalam view controller viewDidLoad metode.

1
- (void)viewDidLoad {
2
    [super viewDidLoad];
3
    
4
    UISwipeGestureRecognizer *showMenuGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showMenu:)];
5
    
6
    showMenuGesture.direction = UISwipeGestureRecognizerDirectionLeft;
7
    
8
    [self.view addGestureRecognizer:showMenuGesture];
9
}

showMenu: metode yang dipicu oleh gerakan recognizer adalah metode private helper yang kami akan terapkan segera. Perhatikan bahwa arah gerakan diatur ke UISwipeGestureRecognizerDirectionLeft, yang berarti bahwa kita ingin menu untuk menganimasikan dari kanan ke kiri.

Dengan gerakan recognizer diinisialisasi, saatnya untuk membuat menu yang menggunakan initializer yang kami terapkan sebelumnya di class MenuComponent. Tambahkan kode snippet berikut ke view controller viewDidLoad metode.

1
    CGRect desiredMenuFrame = CGRectMake(0.0, 20.0, 150.0, self.view.frame.size.height);
2
    self.menuComponent = [[MenuComponent alloc] initMenuWithFrame:desiredMenuFrame
3
                                                       targetView:self.view
4
                                                        direction:menuDirectionRightToLeft
5
                                                          options:@[@"Download", @"Upload", @"E-mail", @"Settings", @"About"]
6
                                                     optionImages:@[@"download", @"upload", @"email", @"settings", @"info"]];

Pastikan bahwa arah Anda memasukan dalam metode inisialisasi cocok dengan gerakan recognizer.

Selanjutnya, menyatakan showMenu: metode dalam class view controller ekstensi.

1
@interface ViewController ()
2
3
@property (nonatomic, strong) MenuComponent *menuComponent;
4
5
- (void)showMenu:(UIGestureRecognizer *)gestureRecognizer;
6
7
@end

Implementasi showMenu: metode tidak bisa lebih mudah.

1
- (void)showMenu:(UIGestureRecognizer *)gestureRecognizer{
2
    [self.menuComponent showMenu];
3
}

Sebelum menjalankan app untuk pertama kalinya, kembali ke MenuComponent.m dan hapus komentar dari invokasi metode setupOptionsTableView dalam metode inisialisasi. Hal ini diperlukan jika kita ingin mencegah aplikasi kita dari crashing, karena kami belum mengimplementasikan protokol tabel view.

1
// Setup the options table view.

2
// [self setupOptionsTableView];

Jalankan aplikasi dan swipe dari kanan ke kiri. Pada titik ini, menu akan muncul, tapi kita tidak bisa membuatnya menghilang dan menu tidak menampilkan pilihan.

Langkah 3: Menyembunyikan Menu

Meskipun swipe gerakan untuk menampilkan menu dilakukan pada view yang dimana menu ditambahkan, gerakan untuk menyembunyikan menu perlu dideteksi oleh menu itu sendiri. Apakah Anda ingat bahwa kami membuat recognizer gerakan dalam class MenuComponent dan hideMenuWithGesture menyatakan:? Metode yang terakhir akan dipanggil ketika menu harus disembunyikan.

Mari kita terapkan hideMenuWithGesture: di MenuComponent.m. Implementasi ini cukup sederhana seperti yang Anda lihat di bawah ini.

1
- (void)hideMenuWithGesture:(UISwipeGestureRecognizer *)gesture {
2
    // Make a call to toggleMenu method for hiding the menu.

3
    [self toggleMenu];
4
    
5
    // Indicate that the menu is not shown.

6
    self.isMenuShown = NO;
7
}

Jika Anda menjalankan aplikasi sekarang, Anda harus mampu menampilkan dan menyembunyikan menu dengan swipe gesture.

9. menu pilihan

Pada menu view sekarang mampu muncul dan menghilang. Saatnya untuk memusatkan perhatian kita pada pengaturan table view pilihan dan menampilkan pilihan menu. Kami sudah mendeklarasikan beberapa pilihan selama inisialisasi menu's dalam view controller viewDidLoad metode. Mari kita lihat apa yang kita perlu lakukan untuk menampilkannya.

Hal pertama yang perlu kita lakukan adalah menerapkan metode yang diperlukan protokol UITableViewDataSource dan UITableViewDelegate. Perhatikan bahwa sel tinggi ditentukan oleh optionCellHeight properti.

1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
2
    return 1;
3
}
4
5
6
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
7
    return [self.menuOptions count];
8
}
9
10
11
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
12
    return self.optionCellHeight;
13
}

Dalam tableView:cellForRowAtIndexPath:, kita mengkonfigurasi sel untuk menampilkan pilihan menu dan gambar. Perhatikan bahwa kita menggunakan objek tableSettings untuk mengkonfigurasi sel-sel table view.

1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
2
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"optionCell"];
3
    
4
    if (cell == nil) {
5
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"optionCell"];
6
    }
7
    
8
    // Set the selection style.

9
    [cell setSelectionStyle:[[self.tableSettings objectForKey:@"selectionStyle"] intValue]];
10
    
11
    // Set the cell's text and specify various properties of it.

12
    cell.textLabel.text = [self.menuOptions objectAtIndex:indexPath.row];
13
    [cell.textLabel setFont:[self.tableSettings objectForKey:@"font"]];
14
    [cell.textLabel setTextAlignment:[[self.tableSettings objectForKey:@"textAlignment"] intValue]];
15
    [cell.textLabel setTextColor:[self.tableSettings objectForKey:@"textColor"]];
16
    
17
    // If the menu option images array is not nil, then set the cell image.

18
    if (self.menuOptionImages != nil) {
19
        [cell.imageView setImage:[UIImage imageNamed:[self.menuOptionImages objectAtIndex:indexPath.row]]];
20
        [cell.imageView setTintColor:[UIColor whiteColor]];
21
    }
22
    
23
    
24
    [cell setBackgroundColor:[UIColor clearColor]];
25
    
26
    return cell;
27
}

Sebelum menjalankan aplikasi, pastikan untuk hapus komentar panggilan untuk setupOptionsTableView.

1
// Setup the options table view.

2
[self setupOptionsTableView];

Hanya itu. Jalankan aplikasi dan swipe dari kanan ke kiri untuk menampilkan menu dan pilihannya.

10. penanganan pilihan pengguna

Seperti yang saya sebutkan sebelumnya, kami tidak akan menerapkan protokol delegasi untuk menu opsi. Sebaliknya, kami akan membuat penggunaan blok. Kami tidak akan menambahkan metode baru. Sebaliknya, kita akan untuk sedikit mengubah metode showMenu. Mulai dengan memperbarui deklarasinya di MenuComponent.h seperti yang ditunjukkan di bawah ini.

1
- (void)showMenuWithSelectionHandler:(void(^)(NSInteger selectedOptionIndex))handler;

showMenu: metode sekarang menerima satu argumen, blok. Blok juga menerima satu argumen, pilihan pengguna.

Ini juga berarti bahwa kita perlu untuk menyimpan blok, karena kita perlu meminta itu ketika pengguna memilih opsi dari menu. Dalam MenuComponent.m, menyatakan properti private untuk menyimpan blok.

1
@interface MenuComponent()
2
...
3
4
@property (nonatomic, strong) void(^selectionHandler)(NSInteger);
5
6
@end

Kita kemudian harus memperbarui showMenu: metode seperti ditunjukkan di bawah.

1
- (void)showMenuWithSelectionHandler:(void (^)(NSInteger))handler {
2
    if (!self.isMenuShown) {
3
        self.selectionHandler = handler;
4
        
5
        [self toggleMenu];
6
        
7
        self.isMenuShown = YES;
8
    }
9
}

Kita mulai dengan menyimpan handler di selectionHandler properti. Setiap kali pengguna memilih item dari table view, kita memanggil handler pilihan. Lihatlah implementasi tableView:didSelectRowAtIndexPath: untuk klarifikasi.

1
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
2
    [[tableView cellForRowAtIndexPath:indexPath] setSelected:NO];
3
    
4
    if (self.selectionHandler) {
5
        self.selectionHandler(indexPath.row);
6
    }
7
}

Akhirnya, kita perlu untuk memperbarui tampilan controller untuk menggunakan showMenu baru: metode. Memperbarui  view controller showMenu: metode, yang akan dipanggil ketika sikap swipe terdeteksi, dengan yang ditunjukkan di bawah ini. Untuk memastikan bahwa semuanya bekerja, kami menampilkan view alert dan menampilkan pilihan pengguna.

1
- (void)showMenu:(UIGestureRecognizer *)gestureRecognizer {
2
    [self.menuComponent showMenuWithSelectionHandler:^(NSInteger selectedOptionIndex) {
3
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIKit Dynamics Menu"
4
                                                        message:[NSString stringWithFormat:@"You selected option #%d", selectedOptionIndex + 1]
5
                                                       delegate:nil
6
                                              cancelButtonTitle:nil
7
                                              otherButtonTitles:@"Okay", nil];
8
        [alert show];
9
    }];
10
}

Jalankan aplikasi sekali lagi untuk memastikan semuanya bekerja seperti yang diharapkan. class komponen menu sudah siap.

Kesimpulan

Dalam tutorial ini, kami telah menciptakan sebuah komponen yang dapat digunakan kembali untuk menampilkan menu menggunakan UIKit Dynamic. Jika UIKit Dynamic baru bagi Anda, maka saya berharap tutorial ini telah memberi Anda rasa apa yang dapat Anda lakukan dengan itu. Merasa bebas untuk bermain-main dengan demo aplikasi untuk menjadi lebih akrab dengan UIKit Dynamic.

Nantikan untuk tutorial selanjutnya di mana kita akan membuat komponen dapat digunakan kembali yang lain, kustom alert view.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.