Xamarin iOS – Custom UIAlertAction Style With SetValueForKey

UIAlertAction merupakan komponen list pada UIAlertController dimana ditampilkan dalam bentuk text. Style pada  UIAlertAction dapat dimodifikasi dengan cara berikut :


     UIAlertAction temp = UIAlertAction.Create(head, UIAlertActionStyle.Default, alert => { /* your function here */ }); 

     temp.SetValueForKey(UIColor.Black, (NSString)"titleTextColor");
     temp.SetValueForKey(UIImage.FromBundle("your image path"), (NSString)"image"); 
     listAlertController.AddAction(temp);

Pada contoh di atas kita membuat sebuah UIAlertAction yang di definisikan pada variabel “temp”. Modifikasi style pada variabel temp dilakukan dengan “SetValueForKey”, dimana kita akan menyisipkan property suatu nilai berdasarkan nama property nya (pastikan property yang di set memiliki nama yang benar, kesalahan nama akan menyebabkan error). Untuk kasus di atas kita melakukan custom property “titleTextColor” untuk warna dari label dan “image” untuk menambahkan icon pada label.

 

Sekian, happy coding…

Xamarin iOS – Dynamic UITabBarController

Xamarin iOS – Dynamic UITabBarController

Untuk kebutuhan yang lebih spesifik, kita dapat membuat kumpulan UIViewController pada UITabBarController secara dinamis. Tahapannya adalah :

  • Tambahkan sebuah UIViewController (xib file) yang akan digunakan secara dinamis pada UITabBarController. Misal dalam contoh ini saya akan membuat sebuah file UIViewController dengan nama “DynamicController”
  • Pada UITabBarController, tambahkan sebuah button atau UITBarButtonItem yang digunakan untuk memberi perintah menambahkan DynamicController ke dalam UITabBar
  • Masukkan code berikut untuk menambah bar dengan DynamicController
 List<UIViewController> temp_list = new List<UIViewController>(this.ViewControllers);
 UIViewController new_tab = new DynamicController();
 new_tab.TabBarItem.Title = "Item #" + (temp_list.Count + 1).ToString();
 temp_list.Add(new_tab);

 this.ViewControllers = temp_list.ToArray();

Yang terjadi pada code di atas adalah :

  • Mendefinisikan variabel temp_list dalam bentuk list dan kita masukkan semua array pada this.ViewControllers (array UIViewController yang sudah ada pada BarItem
  • Mendefinisikan variabel “new_tab” yang berisi UIViewController yang akan ditambahkan
  • Konfigurasi judul TabBar untuk UIViewController “new_tab”
  • Menambahakan list “temp_list” dengan UIViewController baru
  • Atur ulang nilai this.ViewControllers

Source saya ada di : https://github.com/sabithuraira/xamarin_ios_playground/commit/3c5ea649474c69192f264461667082f267e6878b

Happy coding…

Xamarin iOS – Expendable UITableView

Xamarin iOS – Expendable UITableView

Anggaplah saya ingin menampilkan sekumpulan data klub sepak bola ke dalam UITableView. Jika salah satu klub sepak bola di-klik, akan menampilkan daftar pemain pada data tersebut seperti gambaran berikut :

jan-03-2017-10-16-37

Pertama buatlah model untuk mendefinisikan data SoccerClub pada file “SoccerClubModel.cs”, masukkan code berikut :

 using System;
 using System.Collections.Generic;
 
 namespace ios_playground
 {
     public class SoccerClubModel
     {
         private List<string> players;
         private string name;
 
         public SoccerClubModel(string name)
         {
             this.name = name;
             players = new List<string>();
         }
 
         public string Name { 
             get { return this.name;}
         }
 
         public List<string> Players
         {
             get { return this.players; }
             set { this.players = value;}
         }
     }
 }

Code tersebut mendefinisikan class SoccerClubModel dengan variabel nama klub sepak bola dan list nama pemainnya.

Tambahkan sebuah UIViewController dan tambahkan UITableView di dalamnya. Beri nama UITableView tersebut dengan nama “tableExpend”. Paad UITableView yang telah ditambahkan terdapat sebuah UITableViewCell, atur property “Style” -nya menjadi “Right Detail” dan beri identifier “CellChild”.

Kita akan memasuki bagian utama yaitu membuat UITableViewSource yang dapat mendefinisikan Expendable table. Buatlah sebuah class “ExpendableSource” yang akan meng-extend class UITableViewSource. Masukkan code berikut :

 using System;
 using System.Collections.Generic;
 using ObjCRuntime;
 using Foundation;
 using UIKit;
 using CoreGraphics;
 
 namespace ios_playground
 {
     public class ExpendableSource : UITableViewSource
     {
         List<SoccerClubModel> datas;
         NSString childIdentifier = new NSString("CellChild");
         UITableView parentTable;
 
         private bool[] _isSectionOpen;
         private EventHandler _buttonClick;
 
         public ExpendableSource(UITableView parentTable,List<SoccerClubModel> datas)
         {
             this.datas = datas;
             this.parentTable = parentTable;
 
             _isSectionOpen = new bool[datas.Count];
 
             _buttonClick = (sender, e) =>
             {
                 var button = sender as UIButton;
                 var section = button.Tag;
                 _isSectionOpen[(int)section] = !_isSectionOpen[(int)section];
 
                 parentTable.ReloadData();
                 var paths = new NSIndexPath[RowsInSection(parentTable, section)];
                 for (int i = 0; i < paths.Length; i++)
                 {
                     paths[i] = NSIndexPath.FromItemSection(i, section);
                 }
 
                 parentTable.ReloadRows(paths, UITableViewRowAnimation.Automatic);
             };
         }
 
         public override nint NumberOfSections(UITableView tableView)
         {
             return datas.Count;
         }
 
         public override nint RowsInSection(UITableView tableview, nint section)
         {
             return _isSectionOpen[(int)section] ? datas[(int)section].Players.Count : 0;
         }
 
 
         public override nfloat GetHeightForHeader(UITableView tableView, nint section)
         {
             return 44f;
         }
 
         public override nfloat EstimatedHeightForHeader(UITableView tableView, nint section)
         {
             return 44f;
         }
 
         public override UIView GetViewForHeader(UITableView tableView, nint section)
         {
             UIView view = CustomView(datas[(int)section].Name, (int)section);
             return view;
         }
 
         public UIView CustomView(string caption,nint tag)
         {
             UIView view = new UIView(new System.Drawing.RectangleF(0, 0, 320, 20));
             view.BackgroundColor = UIColor.White;
 
             UILabel label = new UILabel();
             label.Font = UIFont.FromName("Helvetica-Bold", 16f);
             label.Frame = new System.Drawing.RectangleF(5, 10, 315, 20);
             label.Text = caption;
             view.AddSubview(label);
 
             UIButton hiddenButton = new UIButton(view.Bounds);
             hiddenButton.Tag = tag;
             hiddenButton.TouchUpInside += _buttonClick;
             view.AddSubview(hiddenButton);
 
             return view;
         }
 
         public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
         {
             UITableViewCell cell = tableView.DequeueReusableCell(childIdentifier);
             if (cell == null)
                 cell = new UITableViewCell(UITableViewCellStyle.Default, childIdentifier);
 
             cell.TextLabel.Text = datas[indexPath.Section].Players[indexPath.Row];
             cell.DetailTextLabel.Text = datas[indexPath.Section].Name;
 
             return cell;
 
         }
     }
 }
 

Berikut penjelasan code di atas :

  • Mendefinisikan variabel datas untuk menyimpan data yang ditampilkan, childIdentifier sebagai identifier dari UITableViewCell yang digunakan, dan parentTable yang akan menghubungkan class dengan tabel yang menggunakannya. Perlakuan yang terjadi pada variabel “parentTabel” akan berpengaruh langsung pada table yang memanggil class ini.
  • Pendefinisian variabel _isSectionOpen untuk variabel penyimpan data mana saja yang sedang menampilkan dan menyembunyikan daftar nama pemain, _buttonClick yang akan menyimpan suatu event.
  • Constructor akan mendefinisikan tableView, datas serta proses yang dilakukan untuk event _buttonClick
  • NumberOfSections sebagai jumlah section pada tabel
  • RowsInSection sebagai jumlah row pada masing-masing section
  • GetHeightForHeader dan EstimatedHeightForHeader untuk tinggi header
  • GetViewForHeader menentukan UIView apa yang ditampilkan pada section header. Header sendiri akan memanggil UIView dari fungsi CustomView() dimana fungsi ini akan menghasilkan sebuah UIView yang terdiri dari sebuah UILabel beserta hidden UIButton yang ketika di klik akan menjalankan event _buttonClick
  • Yang terakhir fungsi GetCell() adalah code yang menampilkan data pada masing-masing row data nama pemain sepak bola.

Selesai.. silahkan running aplikasi anda..

Thanks to https://github.com/b099l3/StackOverflow/tree/master/ExpandableTableView

Code dari tutorial ini dapat juga dilihat di https://github.com/sabithuraira/xamarin_ios_playground/commit/1eccd61bee5720009aef8af99613245bc1161c4d

[Xamarin iOS] Consuming REST API

Setelah memahami cara mengkonsumsi REST API dengan Xamarin android pada tautan berikut, sekarang kita akan mencoba penerapan pada aplikasi iOS dengan Xamarin.

Buatlah sebuah aplikasi iOS pada Xamarin. Design main.storyboard anda seperti berikut :

screen-shot-2016-12-24-at-1-38-22-am

Main.storyboard di atas terdiri dari :

  • UINavigationController
  • MainController : terhubung langsung dengan UINavigationController. MainController terdiri dari sebuah UITableView (kita beri nama “TabelFood”) dan sebuah UITextField (diberi nama “txtTitle”). UITableView secara otomatis memiliki sebuah UITableViewCell, atur style-nya menjadi “Right Detail” dan berilah identifier-nya “CellData”.
  • FormController : Controller ini digunakan untuk melakukan proses edit data (insert, update dan delete). FormController terdiri dari dua buah UITextField guna input data baru yaitu txtName dan txtPrice.
  • Sebuah segue dari UINavigationController ke MainController dengan type segue “root”
  • Sebuah segue dari MainController ke FormController dengan  type “show” dan nama segue “editSegue”

Setelah selesai melakukan pengaturan UI pada masing-masing controller buatlah class FoodMenu.cs sebagai model dari data Food. Masukkan code berikut :

 using System;
 namespace silexiOS
 {
     public class FoodMenu
     {
         private int id;
         private string name;
         private double price;
 
         public FoodMenu(string name, double price)
         {
             this.name = name;
             this.price = price;
         }
 
         public FoodMenu(int id, string name, double price)
         {
             this.id = id;
             this.name = name;
             this.price = price;
         }
 
         public int Id { get { return this.id; } }
 
         public string Name { get { return this.name; } }
         public double Price { get { return this.price; } }
     }
 }
 

Tambahkan package “Newtonsoft.Json” pada project anda untuk memudahkan mengkonsumsi json format yang didapat dari REST API. Buatlah sebuah fungsi “FoodLoader.cs” untuk mengakses REST API dari server, masukkan code berikut :

 using System;
 using System.Collections.Generic;
 using System.Text;
 using System.IO;
 using System.Net;
 using Newtonsoft.Json.Linq;
 
 namespace silexiOS
 {
     public class FoodLoader
     {
         private static readonly string serverLink = "http://localhost/medical/web/index2.php/";
 
         public FoodLoader()
         { }
 
         public static List<FoodMenu> LoadData()
         {
             string link = serverLink + "daftar";
             List<FoodMenu> datas = new List<FoodMenu>();
             try
             {
                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
                 request.Method = "GET";
                 request.ContentType = "application/json";
 
                 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 
                 if (response.StatusCode == HttpStatusCode.OK)
                 {
                     Stream receiveStream = response.GetResponseStream();
                     StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                     string outputString = readStream.ReadToEnd();
 
                     response.Close();
                     readStream.Close();
 
                     outputString = outputString.Trim().Replace("// ", "");
                     var resultArray = JArray.Parse(outputString);
 
                     for (int i = 0; i < resultArray.Count; i++)
                     {
                         var jstock = (JObject)resultArray[i];
 
                         FoodMenu temp_data = new FoodMenu(
                             int.Parse((string)jstock["id"]),
                             (string)jstock["name"],
                             double.Parse((string)jstock["price"])
                         );
 
                         datas.Add(temp_data);
                     }
                 }
             }
             catch (Exception e)
             {
                 throw;
             }
             return datas;
         }
 
         public static String InsertData(FoodMenu data)
         {
             string link = serverLink + "insert";
             String result = "";
             try
             {
                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
 
                 StringBuilder postData = new StringBuilder();
                 postData.Append("name=" + data.Name + "&");
                 postData.Append("price=" + data.Price.ToString());
                 var data_encode = Encoding.ASCII.GetBytes(postData.ToString());
 
                 request.Method = "POST";
                 request.ContentType = "application/x-www-form-urlencoded";
                 request.ContentLength = data_encode.Length;
 
                 using (var stream = request.GetRequestStream())
                 {
                     stream.Write(data_encode, 0, data_encode.Length);
                 }
 
                 var response = (HttpWebResponse)request.GetResponse();
 
                 if (response.StatusCode == HttpStatusCode.OK)
                 {
                     Stream receiveStream = response.GetResponseStream();
                     StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                     result = readStream.ReadToEnd();
 
                     response.Close();
                     readStream.Close();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
             return result;
         }
 
         public static String UpdateData(FoodMenu data, int id)
         {
             string link = serverLink + "update/" + id.ToString();
             String result = "";
             try
             {
                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
 
                 StringBuilder postData = new StringBuilder();
                 postData.Append("name=" + data.Name + "&");
                 postData.Append("price=" + data.Price.ToString());
                 var data_encode = Encoding.ASCII.GetBytes(postData.ToString());
 
                 request.Method = "PUT";
                 request.ContentType = "application/x-www-form-urlencoded";
                 request.ContentLength = data_encode.Length;
 
                 using (var stream = request.GetRequestStream())
                 {
                     stream.Write(data_encode, 0, data_encode.Length);
                 }
 
                 var response = (HttpWebResponse)request.GetResponse();
 
                 if (response.StatusCode == HttpStatusCode.OK)
                 {
                     Stream receiveStream = response.GetResponseStream();
                     StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                     result = readStream.ReadToEnd();
 
                     response.Close();
                     readStream.Close();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
             return result;
         }
 
         public static String DeleteData(int id)
         {
             string link = serverLink + "delete/" + id.ToString();
             String result = "";
             try
             {
                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
                 request.Method = "DELETE";
                 var response = (HttpWebResponse)request.GetResponse();
 
                 if (response.StatusCode == HttpStatusCode.OK)
                 {
                     Stream receiveStream = response.GetResponseStream();
                     StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                     result = readStream.ReadToEnd();
 
                     response.Close();
                     readStream.Close();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
             return result;
         }
     }
 }
 

Dua buah class di atas sama dengan class yang di definisikan pada aplikasi Android yang telah dibuat sebelumnya.

Buatlah class “FoodAdapter.cs” dimana class ini merupakan source yang digunakan untuk mengisi row data pada TabelFood yang ada pada MainController.

 using System;
 using System.Collections.Generic;
 using UIKit;
 using Foundation;
 
 namespace silexiOS
 {
     public class FoodAdapter : UITableViewSource
     {
         private MainController parent;
         private List<FoodMenu> datas = new List<FoodMenu>();
         private string cellIdentifier = "CellData";
 
         public FoodAdapter(MainController parent, List<FoodMenu> datas)
         {
             this.parent = parent;
             this.datas = datas;
         }
 
         public override nint RowsInSection(UITableView tableview, nint section)
         {
             return this.datas.Count;
         }
 
         public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
         {
             var cell = tableView.DequeueReusableCell(cellIdentifier);
 
             if (cell == null)
             {
                 cell = new UITableViewCell(UITableViewCellStyle.Default, cellIdentifier);
             }
 
             cell.TextLabel.Text = this.datas[indexPath.Row].Name;
             cell.DetailTextLabel.Text = this.datas[indexPath.Row].Price.ToString();
             return cell;
         }
     }
 }
 

Sekarang kita akan mulai masuk mengelola code pada MainController dan FormController yang menjalankan proses utama dari aplikasi yang dibuat. Masukkan code berikut pada MainController :

 using Foundation;
 using System;
 using System.Collections.Generic;
 using UIKit;
 
 namespace silexiOS
 {
     public partial class MainController : UIViewController
     {
         public int EditPosition = -1;
         List<FoodMenu> datas = new List<FoodMenu>();
 
         public MainController (IntPtr handle) : base (handle)
         {
         }
 
         public override void ViewWillAppear(bool animated)
         {
             base.ViewWillAppear(animated);
             InitializeView();
         }
 
         public override void ViewDidLoad()
         {
             base.ViewDidLoad();
             this.InitializeBar();
         }
 
         private void InitializeBar()
         {
             List<UIBarButtonItem> rightButtons = new List<UIBarButtonItem>();
 
             rightButtons.Add(new UIBarButtonItem(
                 UIBarButtonSystemItem.Add,
                 (sender, e) => { PerformSegue("editSegue", this); }
             ));
 
             rightButtons.Add(new UIBarButtonItem(
                 UIBarButtonSystemItem.Refresh,
                 (sender, e) => { this.InitializeView(); }
             ));
 
             NavigationItem.RightBarButtonItems = rightButtons.ToArray();
         }
 
         private void InitializeView()
         {
             this.EditPosition = -1;
             txtTitle.Text = "Loading...";
 
             this.datas = FoodLoader.LoadData();
             TabelFood.Source = new FoodAdapter(this, this.datas);
             TabelFood.ReloadData();
 
             txtTitle.Text = "List Food";
         }
 
         public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
         {
             base.PrepareForSegue(segue, sender);
             if (segue.Identifier == "editSegue")
             {
                 var vc = segue.DestinationViewController as FormController;
             }
         }
     }
 }

Yang terjadi pada MainController adalah :

  • Terdapat 2 variabel yang didefinisikan yaitu “EditPosition” dan “datas”. EditPosition digunakan untuk mengetahui posisi data yang di-klik oleh user (ingat kita akan membuat fungsi edit dan delete), sedangkan “datas” akan menyimpan data daftar makanan yang di dapatkan dari REST API.
  • Jika nilai “EditPosition” lebih kecil dari 0 (nol) artinya tidak ada data yang dipilih oleh pengguna.
  • Ketika screen akan muncul maka akan dijalankan fungsi ViewWillAppear dimana fungsi ini akan menjalankan fungsi “InitializeView()”
  • Fungsi “InitializeView()” proses utama-nya adalah mengunduh data yang disediakan dengan REST dimana data yang diunduh langsung ditampilkan pada “TabelFood” yang ada pada screen.
  • Selain menampilkan data ke dalam TabelFood, InitializeView() juga akan memberikan nilai pada “EditPosition” menjadi -1 (ketika kita memanggil/refresh data sudah pasti belum ada data yang dipilih) dan mengeset nilai txtTitle guna menampilkan indikator proses unduh data. Jika proses unduh sedang berjalan, maka txtTitle akan menampilkan tulisan “Loading…”.
  • Setelah menjalankan ViewWillAppear, MainController menjalankan ViewDidLoad() ketika screen telah di load.
  • ViewDidLoad akan menjalankan fungsi “InitializeBar()” dimana fungsi ini akan menambahkan dua buah bar menu pada screen yaitu menu “Add” dan menu “Refresh”.
  • Ketika menu “Add” dipilih maka akan menjalankan fungsi untuk menjalankan segue dimana Controller segue yang dituju adalah form untuk menambahkan data baru. Sedangkan jika menu “Refresh” dipilih, aplikasi akan mengunduh ulang data pada server REST API dan menampilkan ulang data terbaru ke dalam tabel.

Setelah code dijalankan akan muncul screen MainController yang menampilkan data dari server REST API.

Sekarang mari kita membuat code yang akan mengeksekusi code FormController untuk menambah data baru. Masukkan code berikut pada FormController :

 using Foundation;
 using System;
 using System.Collections.Generic;
 using UIKit;
 
 namespace silexiOS
 {
     public partial class FormController : UIViewController
     {
         private int EditId = 0;
         private string EditName;
         private double EditPrice;
 
         public FormController (IntPtr handle) : base (handle)
         {
         }
 
         public override void ViewDidLoad()
         {
             base.ViewDidLoad();
             this.InitializeBar();
             this.InitializeData();
         }
 
         private void InitializeBar()
         {
             List<UIBarButtonItem> rightButtons = new List<UIBarButtonItem>();
 
             rightButtons.Add(new UIBarButtonItem(
                 UIBarButtonSystemItem.Save,
                 (sender, e) => {
                     FoodMenu temp = new FoodMenu(txtName.Text, double.Parse(txtPrice.Text));
                     if (this.EditId == 0)
                         FoodLoader.InsertData(temp);
                     else
                         FoodLoader.UpdateData(temp, EditId);
                     NavigationController.PopViewController(true);
                 }
             ));
 
             if (this.EditId > 0)
             {
                 rightButtons.Add(new UIBarButtonItem(
                     UIBarButtonSystemItem.Trash,
                     (sender, e) =>
                     {
                         FoodLoader.DeleteData(this.EditId);
                         NavigationController.PopViewController(true);
                     }
                 ));
             }
 
             NavigationItem.RightBarButtonItems = rightButtons.ToArray();
         }
 
         private void InitializeData()
         {
             if (this.EditId > 0)
             {
                 this.txtName.Text = EditName;
                 this.txtPrice.Text = EditPrice.ToString();
             }
         }
 
         public void SetEdit(int edit_id, string name,double price)
         {
             this.EditId = edit_id;
             this.EditName = name;
             this.EditPrice = price;
         }
     }
 }

Yang terjadi pada baris code FormController adalah :

  • FormController selain digunakan untuk operasi insert data juga digunakan untuk operasi update dan delete data.
  • FormController memiliki variabel EditId, EditName dan EditPrice. Ketiga variabel tersebut digunakan untuk menyimpan nilai data yang akan di update/delete yaitu nilai id, name dan price -nya.
  • Jika nilai pada EditId bernilai 0 (nol) artinya FormController sedang menjalankan proses untuk input data, sedangkan jika nilai EditId bernilai lebih dari 0 (nol) artinya FormController sedang menjalankan fungsi untuk update data.
  • Ketika screen terbuka maka akan menjalankan fungsi “InitializeBar” dan “InitializeData”.
  • InitializeBar() akan menambahkan top bar menu yaitu menu “Save” (digunakan untuk menyimpan data yang sudah di input) dan menu “Trash” (digunakan untuk menghapus data yang telah dipilih). Menu “Trash” hanya ditampilkan jika FormController dalam mode update data (EditId bukan 0 nol) bukan insert data.
  • Jika tombol “Save” dipilih, maka terdapat dua opsi proses yang dijalankan. Opsi pertama jika nilai EditId == 0, maka  akan dijalankan proses insert data baru. Jika tidak maka akan dijalankan proses untuk memperbaharui data yang sudah ada sesuai dengan EditId yang ada.
  • InitializeData() akan dijalankan jika nilai EditId lebih dari 0 (nol) yang artinya FormController saat ini sedang dalam mode update data.

Saat aplikasi dijalankan, anda akan melihat list data yang berasal dari server REST API dan anda dapat menambahkan data baru untuk diinput pada server. Bagaimana dengan proses delete dan update? Agar dapat menjalankan proses Update dan Delete, masukkan fungsi berikut pada class “FoodAdapter” :

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
            parent.EditPosition = indexPath.Row;
            parent.PerformSegue(editSegue, parent);
        }

Fungsi diatas akan mengeset nilai “EditPosition” pada MainController agar MainController dapat mengetahui data yang mana yang ingin diperaharui oleh user. Kemudian pada MainController perbaharui fungsi PrepareForSegue seperti berikut :

  public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
         {
             base.PrepareForSegue(segue, sender);
             if (segue.Identifier == "editSegue")
             {
                 var vc = segue.DestinationViewController as FormController;
                 if (EditPosition >= 0)
                 {
                     FoodMenu temp = this.datas[EditPosition];
                     vc.SetEdit(temp.Id, temp.Name, temp.Price);
                 }
             }
         }

Ketika proses segue dijalankan aplikasi akan memeriksa jika nilai “EditPosition” > 0 maka peralihan segue akan memanggil fungsi “SetEdit” yang pada FormController dimana guna dari fungsi tersebut adalah untuk melempar data FoodMenu yang ingin diperbaharui..

Selesai..

Silahkan jalankan program anda…

jan-01-2017-09-14-08

Silahkan lihat langsung code saya di https://github.com/sabithuraira/tutor_silex

Xamarin iOS – Use UIWebView

Ya, sebenarnya panduan untuk menggunakan UIWebView pada Xamarin iOS sudah ada di https://developer.xamarin.com/recipes/ios/content_controls/web_view/load_a_web_page/. Tetapi khusus iOS9 dan ke atas terdapat permasalahan munculnya blank page setiap kali load suatu website. Sebagai contoh jika kita ingin melihat tampilan “http://xamarin.com/&#8221; (bukan https), maka yang kita harapkan adalah tampilan seperti berikut :

simulator-screen-shot-nov-27-2016-11-30-02-pm

Bukan tampilan blank page seperti berikut :

screen-shot-2016-11-27-at-11-27-07-pm

Blank page di atas akan menampilkan pesan

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.
Temporary exceptions can be configured via your app's Info.plist file.

Pada “Application Output”-nya. Untuk mengatasi hal tersebut anda harus memodifikasi Info.plist anda agar aplikasi mengizinkan mengakses http. Buka file Info.plist (lebih baik dibuka dengan editor biasa seperti atom/sublime text). Tambahkan konfigurasi berikut di dalam tag <dict> induk :

<key>NSAppTransportSecurity</key>
<dict>
   <key>NSAllowsArbitraryLoads</key>
   <true/>
</dict>

Simpan perubahan tersebut lalu jalankan kembali aplikasi anda.. maka UIWebView sudah dapat menampilkan website dengan http kembali..

Happy coding…

React Native – ListView With Filter Header and Section Header

React Native – ListView With Filter Header and Section Header

Melanjutkan tulisan sebelumnya, kali ini kita akan mencoba menambahkan control untuk melakukan filter pada listview yang telah dibuat seperti gambar berikut :

screen-shot-2016-10-29-at-10-55-08-pm

Sebelum membuat sebuah screen seperti tampilan diatas, kita terlebih dahulu akan membuat sebuah screen yang terdiri dari ListView dan fitur untuk melakukan filter :

screen-shot-2016-10-26-at-3-43-04-pm

Untuk menambahkan component seperti gambar di atas, tambahkan header pada listview yang kita miliki dengan menambahkan code berikut pada code ListView :

         renderHeader={() =>
            <View style={styles.listview_header}>
              <TextInput style={styles.input}
                placeholder="Search..."
                onChangeText={(text) => console.log('searching for ', text)}
              />
            </View>
          }

Code di atas memasukkan code TextInput pada bagian header listview dimana jika diketikkan suatu karakter pada textinput tersebut, maka secara otomatis data pada listview akan difilter berdasarkan karakter yang kita ketikkan. Kok setelah diketik datanya masih belum ter-filter? Emang belum kita buat.. Untuk membuat fitur yang dapat melakukan filter data sesuai dengan data yang dimasukkan pengguna lakukan modifikasi code anda seperti berikut :

const data_array=[‘Music', ‘Movie', ‘Sport', 'Entertainment',];
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

export default class SampleMenu extends Component {
  constructor(props) {
    super(props);
    //definition of listview datasource
    this.state = {
      dataSource: ds.cloneWithRows(data_array),
      filter_string:'',
    };
  }

Rubah code pada bagian constructor seperti code di atas. Apa yang kita lakukan pada perubahan tersebut?

  1. Meletakkan data yang akan ditampilkan pada ListView di luar constructor/class. Kenapa ini dilakukan?
      • Jika data array diletakkan di dalam constuctor, kita tidak dapat menggunakan data array untuk di filter.
      • Antara data array dan dataSource harus dipisahkan sebab ketika proses filter berlangsung maka dataSource akan diperbaharui sesuai dengan data array yang sudah di filter.
  1. Nilai ds kita lettakkan di luar constructor/class. Kenapa?
      • Untuk memperbaharui nilai pada dataSource, kita akan menggunakan nilai ds. Jika diletakkan di constructor kita jadi tidak bisa menggunakan data ds tersebut.

Selain melakukan modifikasi code di atas, kita juga perlu menambahkan code yang akan mengeksekusi proses filter data ketika user memasukkan nilai untuk filter. Perbaharui nilai renderHeader anda seperti code berikut :

 renderHeader={() =>
            <View style={styles.listview_header}>
              <TextInput style={styles.input} placeholder="Search..."
                onChangeText={(text) =>{
                  var rows = [];
                  for (var i=0; i < data_array.length; i++) {
                     var stateName = data_array[i].toLowerCase();
                     if(stateName.search(text.toLowerCase()) !== -1){
                       rows.push(data_array[i]);
                     }
                   }
                   this.setState({dataSource:ds.cloneWithRows(rows)});
                }}
              />
            </View>
          }

Pada code di atas terdapat penambahan pada fungsi “onChangeText”. Code yang kita tambahkan adalah code yang melakukan pengecekan masing-masing data terhadap keyword untuk filter data. Setelah mendapatkan kumpulan data yang sudah sesuai dengan keyword, maka nilai dataSource akan diperbaharui kembali dengan data yang sudah ada. Setelah menambahkan code tersebut aplikasi yang kita buat akan melakukan filter sesuai keyword yang dimasukkan.

screen-shot-2016-10-26-at-11-20-13-pm

Section Header

ListView menyediakan fitur untuk melakukan grouping pada tampilan ListView anda. Hal ini sering digunakan untuk ListView yang memiliki data cukup banyak. Kita akan membuat ListView dengan section header dengan tampilan akhir seperti berikut :

screen-shot-2016-10-29-at-10-55-08-pm

Halaman tersebut menyediakan sebuah ListView dengan Section Header dan fitur filter pada bagian atas ListView. Baiklah, pertama-tama kita harus merubah jenis data yang ada pada ListView. Lakukan perubahan pada variabel data_array yang sebelumnya telah dibuat menjadi seperti berikut :

  const data_array=[];
  data_array['Sport']=['Soccer','Moto GP','Others'];
  data_array['IT & Technology']=['IT','Technology','Science'];
  data_array['Entertainment']=['Music','Movie','Art'];
  data_array['Interest']=['Travel','Style','Fashion','Business'];
  data_array['News & Info']=['Politics','World','Phenomenon'];
  data_array['Health']=['Health','Food','Lifestyle'];

Pada data sebelumnya aplikasi hanya menggunakan data array biasa sedangkan untuk kasus membuat ListView dengan section header data harus di-grouping di masing-masing data. Setelah itu pada constructor anda lakukan perubahan data pada variabel “dataSource” :

      dataSource: ds.cloneWithRowsAndSections(data_array),

Pada code ListView tepatnya code renderSeparator, lakukan perubahan berikut :

 renderSeparator={(sectionId, rowId) => <View key={sectionId+rowId} style={styles.separator_style} />}

Karena dilakukan perubahan pada struktur data_array, maka metode pada fitur filter harus kita modifikasi. Ganti code pada event “onChangeText” pada “renderHeader” menjadi seperti berikut :

                   var rows = [];
                   for (var key in data_array) {
                     if (!rows[key]) {
                       rows[key] = [];
                     }

                     for (var i=0; i < data_array[key].length; i++) {
                        var stateName = data_array[key][i].toLowerCase();
                        if(stateName.search(text.toLowerCase()) !== -1){
                          rows[key].push(data_array[key][i]);
                        }
                      }

                      if(rows[key].length==0)
                        delete rows[key];
                   }

                   this.setState({dataSource:ds.cloneWithRowsAndSections(rows)});

Yang terakhir tambahkan code renderSectionHeader pada ListView anda seperti berikut :

          renderSectionHeader={(rowData,sectionId)=>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionHeaderText}>{sectionId}</Text>
            </View>
          }

Silahkan jalankan aplikasi, jika code yang anda masukkan sudah benar maka akan tampil halaman seperti gambar aplikasi yang diinginkan.

Masih ga jalan?? Silahkan lihat project lengkap dari tulisan ini di : https://github.com/sabithuraira/react_native_playground. Untuk code tulisan ini bisa dicek langsung di https://github.com/sabithuraira/react_native_playground/blob/master/application/components/SampleMenu.js

Happy coding..

React Native – Using ListView

React Native – Using ListView

Untuk menampilkan sekumpulan data kepada pengguna, aplikasi biasanya menggunakan tabel. Untuk aplikasi android sering digunakan ListView, iOS menggunakan UITableView dan pada react native kita akan menggunakan ListView. Kita akan coba membuat sebuah tampilan seperti pada gambar berikut :

screen-shot-2016-10-26-at-1-59-45-pm

Pertama-tama buatlah sebuah componen dengan code listview di dalamnya seperti berikut :

import React, { Component } from 'react';
import {
  StyleSheet, Text, View, ListView, TouchableHighlight,
} from 'react-native';

export default class SampleMenu extends Component {
  constructor(props) {
    super(props);
    //definition of listview datasource
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows([
        'Music', 'Movie', 'Sport', 'Entertainment',
      ])
    };
  }

  render() {
    return (
      <View style={{flex: 1, paddingTop: 22,marginTop:45}}>
        <ListView style={styles.listview_style}
          dataSource={this.state.dataSource}
          renderRow={(rowData,sectionId,rowId) =>(
              <View style={styles.row}>
                <Text style={styles.row_style}>{rowData}</Text>
              </View>
          )}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  listview_style: {
    padding: 10,
    backgroundColor: '#F6F6F6',
  },
  row: {
    flexDirection: 'row',
    backgroundColor: 'white',
  },
  row_style: {
    flex: 1,
    fontSize: 15,
    textAlign: 'left',
    margin: 10,
  },
  separator_style: {
   flex: 1,
   height: StyleSheet.hairlineWidth,
   backgroundColor: '#8E8E8E',
  },
});

Code di atas akan menghasilkan interface seperti berikut :

screen-shot-2016-10-26-at-2-24-00-pm

Agar lebih enak dilihat tambahkan pembatas/separator pada setiap baris.

renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator_style} />}

Tambahkan code tersebut dibawah tag code “renderRow” pada ListView, maka tampilan listview akan berubah menjadi seperti berikut :

screen-shot-2016-10-26-at-2-31-40-pm

Selain menampilkan data, anda juga dapat menambahkan sebuah perintah yang dijalankan ketika pengguna memilih salah satu data. Pada contoh ini kita akan menampilkan sebuah pesan jika pengguna memilih salah satu data.

              <View style={styles.row}>
                <Text style={styles.row_style}>{rowData}</Text>
              </View>

Rubah code di atas menjadi seperti berikut :

            <TouchableHighlight onPress={() => {
                Alert.alert(
                  'Enter title here..',
                  'You click on '+rowData,
                );
            }}>
              <View style={styles.row}>
                <Text style={styles.row_style}>{rowData}</Text>
              </View>
            </TouchableHighlight>

Untuk memberikan respon ketika pengguna menekan suatu data, kita harus menggunakan component “TouchableHighlight”. Setelah menambahkan code tersebut maka ketika pengguna menekan salah satu data akan dijalankan fungsi “onPress”. Pada contoh ini aplikasi yang kita buat akan menampilkan pesan setiap kali pengguna menekan salah satu data.

screen-shot-2016-10-26-at-3-08-06-pm

Selesai, itulah contoh pengembangan aplikasi react native dengan listview sederhana..

Happy coding..

Xamarin iOS – Using UITabBarController

Xamarin iOS – Using UITabBarController

UITabBarController dapat digunakan untuk menyajikan beberapa controller dalam satu screen pada iOS. Bagaimana cara menggunakan UITabBarController pada iOS? dan bagaimana melempar suatu parameter ke seluruh tab yang ada?

Anda dapat menambahkan UITabBarController langsung pada file storyboard. Pilih control UITabBarController dan drag-drop pada storyboard (tambahkan segue agar terhubung dengan aplikasi yang telah dibuat sebelumnya).

screen-shot-2016-11-09-at-12-45-50-pm

Pada contoh di atas kita menghubungkan segue dari UITableCellView ke UITabBarController. Agar dapat membedakan antara UIViewController pada tab1 dan tab2, tambahkan sebuah label pada masing-masing UIViewController.

Tambahkan code berikut pada class “SimpleSource.cs” (lihat postingan Xamarin iOS sebelumnya/lihat pada code github) untuk memberikan sebuah perlakuan ketika pengguna melakukan click pada data :

 public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
 {
     _controller.PerformSegue("TabBar", _controller);
 }

Dan tambahkan code berikut pada constructor-nya :

 //definition WelcomeController to get parent controller
 WelcomeController _controller;
 public SimpleSource(WelcomeController _controller, List<Player> datas)
 {
     this.datas = datas;
     this._controller = _controller;
 }

Jalankan aplikasi dan akan muncul tampilan seperti berikut :

uitabbar

Bagaimana cara melempar parameter di semua tab kemudian melakukan refresh pada semua tab tersebut? Mari tambahkan sebuah UIBarButtonItem pada TabController kita, dengan menambahkan code berikut pada class “TabController.cs” :

 public override void ViewDidLoad()
 {
     base.ViewDidLoad();
     this.InitializeBar();
 }

 private void InitializeBar()
 {
     UIBarButtonItem t1 = new UIBarButtonItem(
        UIBarButtonSystemItem.Add
        (s, e) =>
        {//this space will use for run procces when click
        }
     );

     NavigationItem.RightBarButtonItem = t1;
 }

Buatlah sebuah interface bernama “TabInterface.cs” yang akan di-extend oleh UIViewController pada setiap class pada Tab Bar, masukkan code berikut :

using System.Collections.Generic;

namespace ios_playground
{
   public interface TabInterface
   {
       void ReloadScreen(int click);
   }
}

Pada Tab1Controller.cs dan Tab2Controller.cs extend class “TabInterface” dan buat sebuah fungsi void ReloadScreen :

 public partial class Tab1Controller : UIViewController, TabInterface
 {
        string label_text = "Tab1";
        public Tab1Controller (IntPtr handle) : base (handle)

        {

        }

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            this.Lbl_item.Text = label_text;
        }

        public void ReloadScreen(int click)
        {
            label_text = "Tab1 : You tab me " + click.ToString() + " time(s)";
            if (this.Lbl_item != null)
                this.Lbl_item.Text = label_text;
        }
    }

Tab2Controller.cs :

 public partial class Tab2Controller : UIViewController, TabInterface
 {
        string label_text = "Tab2";
        public Tab2Controller (IntPtr handle) : base (handle)
        {
        }

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            this.Lbl_Item.Text = label_text;
        }

        public void ReloadScreen(int click)
        {
            this.label_text = "Tab 2 : You tab me " + click.ToString() + " time(s)";
            if (this.Lbl_Item != null)
                this.Lbl_Item.Text = label_text;
        }
    } 

Sekarang kembali pada TabController.cs, masukkan code berikut pada UIBarButtonItem yang telah dibuat sebelumnya :

 public override void ViewDidLoad()
 {
     base.ViewDidLoad();
     this.InitializeBar();
 }

 private int click_count = 0;
 private void InitializeBar()
 {
     UIBarButtonItem t1 = new UIBarButtonItem(
         UIBarButtonSystemItem.Add
         (s, e) =>
         {
             ++click_count;
             foreach (UIViewController temp in this.ViewControllers)
             {
                TabInterface pi = (TabInterface)temp;
                pi.ReloadScreen(click_count);
             }
         }
    );

    NavigationItem.RightBarButtonItem = t1;
 }

Berikut adalah tampilan aplikasi setelah dijalankan :

uitabbar2

Pada video tersebut kedua bar akan merefresh nilai label setiap kali di klik pada bar button “+” pada bagian atas..

Happy coding..

Xamarin iOS – Using UITableView with Custom Cell

Xamarin iOS – Using UITableView with Custom Cell

Salah satu control yang cukup sering digunakan pada pengembangan aplikasi adalah table. Pada iOS table sering ditampilkan dengan menggunakan sebuah control bernama UITableView (bagi anda yang familiar dengan Android, control ini mirip dengan ListView). Bagaimana menggunakan UITableView pada Xamarin?

Anda dapat menambahkan UITableView yang dipilih dari “toolbox” dan memasukkannya ke dalam UIViewController. Pada tulisan ini saya akan menambahkan UITableView ke dalam WelcomeController yang sudah dibuat pada tulisan sebelumnya. Tampilan design storyboard setelah penambahan UITableView adalah sebagai berikut :

screen-shot-2016-11-02-at-12-30-37-pm

Beri initial pada UITableView yang sudah ditambahkan dengan nama “My_Table”. UITableView akan menampilkan sekumpulan data dimana setiap row data akan diletakkan pada sebuah UITableViewCell. UITableViewCell sendiri secara default sudah include di dalam UITableView seperti gambar berikut :

screen-shot-2016-11-02-at-12-49-20-pm

Setiap UITableView dapat memiliki beberapa jenis UITableViewCell yang memiliki tampilan berbeda-beda sesuai kebutuhan. Pastikan anda memberi identitas “identifier” pada setiap UITableViewCell agar dapat dikenali oleh aplikasi, pada contoh ini saya akan berikan identifier  pada cell saya dengan nama “Simple_Cell”.

UITableViewCell memiliki beberapa jenis tampilan untuk dipilih :

screen-shot-2016-11-02-at-12-52-36-pm

Jika anda memilih jenis selain “Custom” maka UITableViewCell akan memiliki tampilan simple  yang sudah memiliki format default dari iOS seperti berikut :

pizap-com14780667820401

Berikut adalah contoh membuat UITableView dengan tampilan “Right Detail”. Pertama-tama silahkan atur property UITableViewCell style anda dengan style “Right Detail”. Aplikasi yang kita buat akan membuat screen dengan sebuah UITableView yang akan menampilkan daftar nama football player beserta club-nya. Buat terlebih dahulu class model untuk Player, tambahkan sebuah class dengan nama “Player.cs” dan masukkan code berikut :

namespace ios_playground
{
   public class Player
   {
      private string name;
      private string club;

      public Player(string name,string club)
      {
          this.name = name;
          this.club = club;
      }

      public string Name
      {
           get { return this.name; }
      }

      public string Club
      {
           get { return this.club; }
      }
   }
}

UITableView akan menampilkan data source yang berasal dari class “UITableViewSource”. Class yang meng-extend UITableViewSource inilah yang akan mengeksuksi tampilan yang muncul pada setiap row data beserta event yang dilaksanakan pada setiap row. Buatlah sebuah class “SimpleSource” yang akan meng-extend class UITableViewSource dan masukkan code seperti berikut :

using System;
using System.Collections.Generic;
using Foundation;
using UIKit;

namespace ios_playground
{
   public class SimpleSource : UITableViewSource
   {
       //variable yang menyimpan list data
       List<Player> datas;
       //identifier cell yang akan ditampilkan
       string CellIdentifier = "Simple_Cell";

       public SimpleSource(List<Player> datas)
       {
           this.datas = datas;
       }

       public override nint RowsInSection(UITableView tableview, nint section)
       {
            return datas.Count;
       }

       public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
       {
            UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
            Player single_data = this.datas[indexPath.Row];

            if (cell == null)
            { 
                cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); 
            }

            //konfigurasi data.Name ke textLabel sedangkan data.Club ditampilkan pada detailTextLabel
            cell.TextLabel.Text = single_data.Name;
            cell.DetailTextLabel.Text = single_data.Club;

            return cell;
        }
    }
}

Class di atas menampilkan row data class Player yang dikirim dari parameter constructor. Untuk menampilkan data tersebut pada UITableView WelcomeController, masukkan code berikut pada class “WelcomeController”.

        //definisikan variabel datas untuk menyimpan kumpulan data “Player”
        private List<Player> datas;

        public WelcomeController (IntPtr handle) : base (handle)
        {
           this.datas = new List<Player>();
        }

Pada class ViewDidLoad(), masukkan code berikut :

 this.datas.Add(new Player("Christiano Ronaldo", "Real Madrid"));
 this.datas.Add(new Player("Lionel Messi", "Barcelona"));
 this.datas.Add(new Player("Gareth Bale", "Real Madrid"));
 this.datas.Add(new Player("Zlatan Ibrahimovic", "Manchester United"));
 this.datas.Add(new Player("Mesut Ozil", "Arsenal"));

 //konfigurasi source table dengan class SimpleSource
 this.My_Table.Source = new SimpleSource(this.datas);

Code di atas menambahkan data Player ke dalam list, list yang sudah ada akan dilempar kedalam class “SimpleSource”. Tampilan berikut akan muncul setelah anda menjalankan aplikasi :

screen-shot-2016-11-02-at-2-08-02-pm

Custom UITableViewCell

Ada banyak kebutuhan dimana kita diharuskan menampilkan UITableViewCell dengan tampilan yang kompleks dan sering digunakan di berbagai tabel. Untuk mengatasi permasalahan tersebut kita dapat membuat sebuah custom UITableViewCell, berikut caranya.

Buatlah sebuah file “TableViewCell” baru :

screen-shot-2016-11-02-at-9-21-57-pm

Berilah nama “SimpleCustomCell” pada file tersebut. Setelah membuat SimpleCustomCell, maka akan terbentuk dua buah file yaitu “SimpleCustomCell.cs” sebagai class dari TableViewCell dan “SimpleCustomCell.xib” yang merupakan file UI dari TableViewCell. Buka data .xib dan buat UI seperti berikut:

screen-shot-2016-11-02-at-9-29-05-pm

TableViewCell terdiri dari tiga buah UILabel. Silahkan beri identitas nama pada masing-masing label: “label name” bernama “name”, “label club” bernama “club dan “label country” bernama “country”. Setelah memberi identitas masing-masing UILabel, berikan identitas “identifier” untuk UITableViewCell dengan nama “Custom_Cell”. Buka class “SimpleCustomCell.cs” dan masukkan code berikut :

using System;
using Foundation;
using UIKit;

namespace ios_playground
{
   public partial class SimpleCustomCell : UITableViewCell
   {
      protected SimpleCustomCell(IntPtr handle) : base(handle)
      {}

      public SimpleCustomCell() : base()
      {}

      //update row with current data
      public void UpdateCell(Player data)
      {
         Name.Text = data.Name;
         Club.Text = data.Club;
         Country.Text = data.Country;
       }
    }
}

Karena data player bertambah satu buah field yaitu field “Negara” maka tambahkan code berikut pada class Player:

 private string country;

 //lakukan perubahan pada constuctor
 public Player(string name,string club, string country)
 {
   this.name = name;
   this.club = club;
   this.country = country;
 }

 public string Country 
 { 
    get { return this.country; }
 }

Masukkan code berikut pada class “SimpleSource” :

using System;
using System.Collections.Generic;
using ObjCRuntime;
using Foundation;
using UIKit;

namespace ios_playground
{

  public class SimpleSource : UITableViewSource
  {
     List<Player> datas;
     NSString CellIdentifier = new NSString("Custom_Cell");

     public SimpleSource(List<Player> datas)
     {
        this.datas = datas;
     }

     public override nint RowsInSection(UITableView tableview, nint section)
     {
       return datas.Count;
     }

     public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
     {
        Player single_data = this.datas[indexPath.Row];
        SimpleCustomCell cell = tableView.DequeueReusableCell(CellIdentifier) as SimpleCustomCell;

        if (cell == null)
        {
           cell = new SimpleCustomCell();
           var views = NSBundle.MainBundle.LoadNib("SimpleCustomCell", cell, null);
           cell = Runtime.GetNSObject(views.ValueAt(0)) as SimpleCustomCell;
        }

        //update data cell
        cell.UpdateCell(single_data);
        return cell;
      }
   }
}

Berikut tampilan aplikasi setelah dijalankan :

screen-shot-2016-11-02-at-9-51-28-pm

Selamat mencoba.. Happy coding..

React Native – Understanding Props and State

React Native – Understanding Props and State

Selain Component dan JSX, dalam React Native anda juga akan sangat sering menemui Props dan State. Apa itu Props dan State?

Props

Dalam pengembangan aplikasi kita mungkin sering menggunakan parameter pada suatu fungsi. atau class. React native sendiri menyediakan sebuah opsi untuk mempermudah developer mengelola parameter pada suatu component yang disebut Props. Props sendiri bisa dibilang adalah sebuah parameter default yang dimiliki oleh suatu component dimana ketika anda memanggil sebuah component, anda dapat menentukan/insert nilai props untuk component tersebut. Sebagai contoh penggunaan props adalah seperti berikut :

//class ini akan menampilkan jumlah huruf yang ada pada
//suatu karakter.

class CountOfCharacter extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
        <Text style={styles.welcome}>
          //menampilkan jumlah huruf dari variabel props.text
          Count of character : {this.props.text.length}
        </Text>
    );
  }
}

Silahkan hapus baris komentar yang berawalan “//“.

Code di atas adalah salah satu contoh penggunaan props pada suatu component. Kita dapat memanggil class di atas dengan cara seperti berikut :

        <CountOfCharacter text=‘Text Saya' />

Pemanggilan tag tersebut akan mencetak tampilan “Count of character : 9”

Props digunakan untuk melempar parameter yang berasal dari luar class component/dari component yang memanggilnya. Props juga tidak mengizinkan modifikasi nilai props di dalam class component-nya dan pada teorinya penggunaan parameter memang tidak dirancang untuk dimanipulasi/diubah-ubah. Bagaimana jika alur aplikasi kita memerlukan data props untuk dimodifikasi? Anda dapat gunakan variabel lain atau gunakan “state”. Lalu bagaimana jika saya butuh variabel untuk mengelola informasi dalam suatu component? Anda juga dapat gunakan variabel lain atau gunakan “state”.

State

State bisa dibilang adalah variabel default yang dimiliki suatu component yang nilainya dapat diubah-ubah. Nilai pada state harus didefinisikan terlebih dahulu pada constructor suatu component. Berikut contoh penggunaan state:

Jika pada pemrograman C# atau Java sering ditemui pendefinisian variabel seperti berikut :

 private string name;
 private string address;

Pada react native mendefinisikan nilai tersebut di dalam state dengan cara seperti berikut :

constructor(props) {
    super(props);
    this.state = { name: ‘Sabit',address:'South Sumatera, Indonesia’ };
  }

Dengan ditanamkannya nilai this.state.name dan this.state.address, anda dapat menggunakan variabel tersebut di seluruh class component bersangkutan. Anda juga dapat merubah nilai dari state dengan cara seperti berikut :

 this.setState({name:new_value}) // code ini akan merubah nilai this.state.name
 this.setState({address:new_value}) // gunakan code ini untuk merubah this.state.address

Berikut adalah contoh aplikasi lengkap penggunaan state dan props :

import React, { Component } from 'react';
import {
  AppRegistry, StyleSheet, Text, TextInput, View
} from 'react-native';

export default class myfirstApp extends Component {
  constructor(props) {
    super(props);
    this.state = { text: '',text2:'Awesome' };
  }

  render() {
    let judul='React Native';
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to {judul} {this.state.text2}!
        </Text>
        <TextInput
          style={{height: 40, margin: 15, padding: 10, 
            borderColor: 'gray', borderWidth: 1}}
          onChangeText={(text) => this.setState({text})}
        />
        <CountOfCharacter text={this.state.text} />
      </View>
    );
  }
}

//class ini akan menampilkan jumlah huruf yang ada pada
//suatu karakter
class CountOfCharacter extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
          //akan menampilkan jumlah huruf dari variabel props.text
        <Text style={styles.welcome}>
          Count of character : {this.props.text.length}
        </Text>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('myfirstApp', () => myfirstApp);

Itu adalah contoh aplikasi untuk melakukan penghitungan huruf yang telah diinput. Tampilan dari aplikasi adalah sebagai berikut :

screen-shot-2016-11-02-at-11-19-26-am

Jika code anda sudah benar, maka akan tampil screen seperti gambar diatas.. Happy coding..