تطبيق iOS: العمل مع MultiComponent Picker



تدور هذه المدونة حول إنشاء تطبيق ios يعرض التحويل من وحدة إلى أخرى. يصف عمل منتقي المكونات المتعددة والتنبيهات وما إلى ذلك.

للحصول على نظرة شاملة ، من فضلك اقرأ . هذه هي المدونة الثانية من سلسلة تطبيقات iOS.





إذا كنت مطورًا متمرسًا ولديك فضول بشأن عمل منتقي MultiComponent ، فقد وصلت إلى المدونة الصحيحة. في هذه المدونة ، سأتحدث عن كيفية توسيع تطبيق التحويل الخاص بنا بمزيد من الوظائف من خلال تنفيذ منتقي متعدد المكونات ، وكذلك كيفية إجراء معالجة استثنائية باستخدام التنبيهات.

في الآخر مدونة ،لقد رأينا ذلك عندما نكتب شيئًا ما في حقل النص ، تنبثق لوحة المفاتيح. يتم كتابة القيمة المراد تحويلها في حقل النص ثم نرى أن لوحة المفاتيح لا تختفي.



لحل هذه المشكلة ، يتعين علينا إضافة زر يغطي العرض بالكامل. عندما يلمس المستخدم أي مكان في الخلفية ، يجب أن تختفي لوحة المفاتيح.

الآن ، دعونا نمضي قدمًا ونفعل ذلك. اسحب زرًا ، واضبط نوع الزر على أنه لون مخصص ونص كلون واضح من مفتش السمات.

مفتش السمات



وحدد محرر> ترتيب> إرسال إلى الخلف

ما هو مزج البيانات في اللوحة

وقم بتغيير حجم الزر بحيث يناسب العرض بالكامل.

يعمل هذا الزر الآن كزر غير مرئي في الخلفية يتم النقر عليه حتى تختفي لوحة المفاتيح. دعونا نكتب IBAction لنفسه ، حدد وضع المحرر المساعد وتحكم + اسحب إلى ViewController.h. عيّن الاتصال بالإجراء والاسم على BackgroundButton وانقر فوق اتصال.

يبدو رمز وحدة التحكم في العرض بهذا الشكل الآن.

#importinterface ViewController: UIViewControllerproperty (strong، nonatomic) IBOutlet UITextField * ValueTextFieldproperty (strong، nonatomic) IBOutlet UIPickerView * picker2property (strong، nonatomic) NSArray * dataproperty (strong، nonletatomic) IBOutlet - (IBAction) تحويل: (UIButton *) sender - (IBAction) backgroundButton: (id) senderend

قم بالتبديل إلى ViewController.m ثم اكتب التعليمات البرمجية التالية.

- (IBAction) backgroundButton: (id) المرسل {[_ValueTextField resignFirstResponder] [_picker2 resignFirstResponder] [_ResultLabel resignFirstResponder]}

هنا يخبر الرمز جميع الكائنات الأخرى بإعطاء حالة المستجيب الأول عند اكتشاف اللمس. الآن ، قم بتشغيل التطبيق وشاهد. ستتمكن من العثور على لوحة المفاتيح تختفي عند لمس الخلفية. الآن لكي تنتقل لوحة المفاتيح عند الانتهاء من الكتابة ، قم باستدعاء طريقة backgroundButton في طريقة didselectRow () الخاصة بالمنتقي. لذا فإن كود الطريقة سيكون على النحو التالي.

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) component {selectedValue = _data [row] [self backgroundButton: 0]}

الآن ، يمكنك العمل على جزء التجميل من التطبيق ، مثل إضافة خلفية وربما حتى إعطاء صورة زر رائعة. ومع ذلك ، في بلدي ، سوف أقوم بتعيين صورة الخلفية.
للقيام بذلك ، ابحث عن الصورة المناسبة أولاً! ثم قم بإضافته إلى المجلد Images.xcassets وقم بتغيير الصورة من شاشة 1x إلى 2x بشكل عام.

قم بتشغيل التطبيق ومعرفة ما إذا كان يعمل بشكل جيد.

إذا قمت بتغيير الجهاز إلى iphone 5s.

وقم بتشغيل التطبيق.

هنا يمكننا أن نرى أن كل شيء يعمل بشكل جيد كما هو متوقع. الآن ماذا لو أردت إضافة خلفية إلى الزر الخاص بي وجعل المظهر أشبه بالزر؟ للقيام بذلك ، أود أولاً إضافة IBOutlet لزر التحويل إلى ViewController.h

property (قوي ، غير ذري) IBOutlet UIButton * convert

ثم قم بإضافة التعليمات البرمجية التالية في طريقة viewDidLoad ()

self.convert.backgroundColor = [UIColor colorWithRed: 0.4 أخضر: 0.8 أزرق: 1.0 alpha: 1.0] [_convert setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal]

دعونا ندير تطبيقنا ونرى ما إذا كانت هذه هي الطريقة التي نحبها.

حسنا عظيم! يجب أن تكون قد لاحظت أنني قمت بتغيير مواضع تسمية النتيجة أيضًا ، وسبب التغيير هو شيء سأقوم بشرحه لاحقًا.

نعلم أن تطبيقنا يتحول من الدرجة المئوية إلى فهرنهايت والعكس صحيح فقط. إذن ، ماذا عن إضافة عدد قليل من الوظائف أو الوحدات للتحويل؟ للقيام بذلك ، نحتاج إلى إضافة مكون آخر إلى UIPickerView الذي يعطي التحديد المناسب ، عند تحديد وحدة في المكون الأول من المنتقي.

لإنشاء منتقي مقسم إلى مكونين ، نحتاج إلى إضافة بيانات NSArray جديدة 2 ، والتي ستحتفظ ببيانات المكون الثاني. حدد أيضًا ثابتين يمثلان عنصرين. هنا ، يتم الإعلان عن المكون الأيسر 0 والمكون الأيمن يتم الإعلان عنه 1 من أجل بساطة البرمجة.

يبدو ملف ViewController.h الخاص بك بالشكل

#import # عرّف data1comp 0 # حدد data2comp 1interface ViewController: UIViewControllerproperty (strong، nonatomic) IBOutlet UITextField * ValueTextFieldproperty (strong، nonatomic) IBOutlet UIPickerView * picker2property (strong، nonatomic) @ NSA قوي ، غير ذري) NSArray * data2property (strong، nonatomic) IBOutlet UILabel * ResultLabelproperty (strong، nonatomic) IBOutlet UIButton * convert - (IBAction) التحويل: (UIButton *) المرسل - (IBAction) backgroundButton: (id) sender @النهاية

الآن حدد مجموعة data2 في طريقة ViewDidLoad (). الآن بعد أن أصبح لدينا كلا مصدري البيانات ، يجب أن نكون قادرين على كتابة التعليمات البرمجية للمنتقي بطريقة أنه عندما نختار عنصرًا من المكون الأول للمنتقي ، يجب تغيير المكون الثاني تلقائيًا إلى القيمة المقابلة. المكون الثاني يعتمد على اختيار الأول.
لهذا ، نحتاج إلى تحديد قاموس يخزن المفاتيح والقيم. تحتوي المفاتيح على البيانات المقابلة للمكون الأول في المنتقي ، وتحتوي القيم على البيانات المقابلة للمكون الثاني من المنتقي.

- (باطل) viewDidLoad {[super viewDidLoad] // قم بأي إعداد إضافي بعد تحميل العرض ، عادةً من طرف المنقار. _data1 = [NSArray arrayWithObjects: @ 'Celsius'، @ 'Fahrenheit'، @ 'Meter'، @ 'Centimeter، nil] data2 = [NSArray arrayWithObjects: @' Centimeter '، @' Meter '، @' Fahrenheit '، @ 'Celsius'، nil] القاموس = [قاموس NSD DictionaryWithObjectsAndKeys: @ 'Celcius'، @ 'Farenheit'، @ 'Farenheit'، @ 'Celcius'، @ 'Meter'، @ 'Centimeter'، @ 'Centimeter'، @ 'Meter '، nil] self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: (@' bg2.png ')]]}

الآن ، يجب علينا تغيير مصدر البيانات وتفويض طرق المنتقي الحالي إلى ما يلي ، حتى نتمكن من تعبئة البيانات في كلا المكونين.

- (NSInteger) numberOfComponentsInPickerView: (UIPickerView *) pickerView {return 2} - (NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {if (component == data1comp) count {return [self.data1 count] [self.data2 count]} - (NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) row forComponent: (NSInteger) component {if (component == data1comp) {return [self.data1 objectAtIndex: row]} return [self.data2 objectAtIndex: row]} - (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: row] NSArray * a = [Dictionary objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animated: YES] [_picker2 reloadComponent: data2comp selected11 = row}}

هنا في طريقة didSelectRow () الخاصة بنا ، نحصل على القيمة المحددة للمكون الأول ، ثم نقوم بتمريرها كوسيطة إلى طريقة objectForKey () في القاموس ، ونحصل على القيمة المقابلة للمفتاح. للعثور على الموضع المقابل للقيمة في المصفوفة الثانية ، أي data2 ، نستخدم طريقة indexOfObject () للصفيف ونخزن النتيجة في قيمة عدد صحيح.
نقوم بعد ذلك بتمرير قيمة العدد الصحيح إلى طريقة المنتقي selectRow: row inComponent: component (). وأعد تحميل مكون المنتقي باستخدام reloadComponent ().
بمجرد القيام بذلك ، عندما نختار عنصرًا واحدًا من المكون الأول ، سيتم تحديد العنصر المقابل في المكون الثاني من المنتقي.

رمز didSelectRow ()

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: row] NSArray * a = [Dictionary objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animated: YES] [_picker2 reloadComponent: data2comp] selectedValue = data11 selectedRow = row}}

قم الآن بتشغيل التطبيق ومعرفة ما إذا كان المنتقي يعمل كما هو متوقع.

هاهو! إنها تعمل!

لذلك دعونا نواصل كتابة زر التحويل الخاص بنا. كان للمنتقي السابق قيمتان فقط لمطابقتهما ، أي مئوية وفهرنهايت ، ثم تم حساب النتيجة. ولكن لدينا الآن أربع قيم هي الدرجة المئوية والفهرنهايت والمتر والسنتيمتر. لذلك استخدمت بيان تبديل ، يحسب القيمة بناءً على متغير الصف المحدد.

- (IBAction) تحويل: (UIButton *) المرسل {float val = [_ ValueTextField.text floatValue] NSLog (@ 'value٪ f'، val) switch (selectedRow) {case 0: // Celsius to Fahrenheit res = (val * 1.8) + 32 حالة كسر 1: // فهرنهايت إلى درجة مئوية res = (val-32) /1.8 حالة كسر 2: // متر إلى سنتيمتر res = val * 100 حالة كسر 3: // سنتيمتر إلى متر res = val * 0.01 استراحة الافتراضي: res = 0.0} NSString * final = [NSString stringWithFormat: @ '٪. 02f'، res] _ResultLabel.text = final}

إذا قمت بتشغيل التطبيق ، يمكننا أن نرى أن كل شيء يعمل بشكل جيد.

الفرق بين javascript و jquery

الآن ، يمكننا التحقق من الاستثناءات التي يمكن أن تحدث في تطبيقنا. على سبيل المثال ، لا توجد قيمة في مربع النص. أو نحاول التحويل من الدرجة المئوية إلى المتر أو السنتيمتر ، وهو أمر غير ممكن بالفعل. تسمى هذه الأنواع من المواقف كاستثناءات ويجب علينا تجنبها عن طريق كتابة تعليمات برمجية للتعامل مع مثل هذه الأخطاء.

دعنا نحل النوع الأول من الخطأ الذي يمكن أن يحدث عند تشغيل تطبيقنا. أي أننا نفتقد كتابة القيمة التي نريد تحويلها في حقل النص. بالنسبة لهذا السيناريو ، يجب علينا تنبيه مستخدمينا لإدخال القيمة ثم المتابعة.

يمكننا استخدام UIAlertView لهذا الغرض. يمكننا كتابة رسالة باسم showAlertWithMessage (NSString *). في هذه الطريقة ، يمكننا الإعلان عن alertView ثم عرضها أخيرًا باستخدام طريقة show (). سيكون رمز الطريقة على النحو التالي.

- (باطل) showAlertWithMessage: (NSString *) رسالة {UIAlertView * alertView = [[تخصيص UIAlertView] initWithTitle: @ رسالة 'خطأ': مفوض الرسالة: self cancellButtonTitle: nil otherButtonTitles: @ 'Okay'، nil] alertView.tag = 100 _ResultLabel.text=@'No Result '[alertView show]}

الآن هذه الطريقة عندما ينقر المستخدم على زر التحويل يجب أن تسمى التحويل. لا ينبغي أن يتم التحويل دون إدخال القيمة. لذلك في تعريف طريقة التحويل ، يجب أن نتحقق مما إذا كان طول حقل النص أكبر من أو يساوي صفرًا أم لا. إذا كان الأمر كذلك ، فقم بإجراء التحويل ، وإلا اعرض التنبيه. لذلك ، سيكون رمز زر التحويل كما يلي:

- (IBAction) تحويل: (UIButton *) المرسل {if ([_ ValueTextField.text length]<= 0) { [self showAlertWithMessage:@' Please enter the value'] } else { float res=0.0 float val=[_ValueTextField.text floatValue] NSLog(@'value %f',val) switch(selectedRow) { case 0:// Celsius to Fahrenheit res=(val*1.8)+32break case 1: // Fahrenheit to Celsius res=(val-32)/1.8break case 2: // meter to centimeter res= val*100 break case 3://centimeter to meter res=val*0.01 break default: res=0.0 } NSString *final= [NSString stringWithFormat:@'%.02f',res] _ResultLabel.text = final } }

الآن قم بتشغيل التطبيق وحاول النقر فوق زر التحويل دون إدخال القيم في حقل النص.

النوع الثاني من الاستثناءات التي يمكن أن تحدث إذا كانت القيمة في المكون الأول لا تتطابق مع القيمة الموجودة في المكون الثاني من UIPickerView. لهذا ، نتحقق مما إذا كانت قيمة صف المكون المحدد الحالي للمكون الثاني تساوي قيمة قيمة الصف التي تم إرجاعها بواسطة مندوب didSelectRow () للطريقة. إذا لم يكن الشرط متطابقًا ، فلن يكون التحويل ممكنًا وإذا تطابقت القيم ، فيمكن إجراء التحويل.

يمكننا تنفيذ هذا المنطق على النحو التالي ،

- (IBAction) تحويل: (UIButton *) المرسل {if ([_ ValueTextField.text length]<= 0) { [self showAlertWithMessage:@' Please enter the value'] } else { _ResultLabel.textColor= [UIColor blackColor] float res=0.0 NSInteger n =[_picker2 selectedRowInComponent:data2comp] if(n==secondrow) { float val=[_ValueTextField.text floatValue] NSLog(@'value %f',val) switch(selectedRow) { case 0:// Celsius to Fahrenheit res=(val*1.8)+32break case 1: // Fahrenheit to Celsius res=(val-32)/1.8break case 2: // meter to centimeter res= val*100 break case 3://centimeter to meter res=val*0.01 break default: res=0.0 } NSString *final= [NSString stringWithFormat:@'%.02f',res] _ResultLabel.text = final } else { // code for displaying error. _ResultLabel.textColor= [UIColor redColor] _ResultLabel.text = @'Result cannot be calculated' } }

الآن قم بتشغيل التطبيق وانظر من خلال تغيير القيمة في المكون الثاني بعد إجراء التحديد في المكون الأول.

يمكنك رؤية رسالة الخطأ التي لا يمكن حساب النتيجة. ستلاحظ أن رسالة الخطأ قد تمت طباعتها في نفس تسمية النتيجة ، وأن الرسالة طويلة. ولهذا السبب تم نقل التسمية لأسفل من الاتجاه السابق.

لذلك ، اكتمل تطبيق التحويل لدينا. يمكنك إضافة المزيد من الوظائف إلى التطبيق وفقًا لاختيارك وجعله أكثر جمالًا وفقًا لإبداعك.

لديك سؤال لنا؟ أذكرها في قسم التعليقات وسنعاود الاتصال بك.

المنشورات ذات الصلة: