# iOS অ্যাপে ব্যাসিক ইনপুট আউটপুট ও কিবোর্ড হ্যান্ডেলিং

**ভূমিকাঃ** এই চ্যাপ্টারে আমরা iOS অ্যাপে কিভাবে সাধারণ ডাটা ইনপুট দেয়া যায় এবং সেটা কিভাবে হ্যান্ডেল করতে হয় তা আলোচনা করবো। ডাটা ইনপুট এর সাথে সাথে যেহেতু কিবোর্ড এর ব্যাপারটাও চলে আসে তাই কিবোর্ড হ্যান্ডেলিং নিয়েও সহজ কিন্তু সবসময় কাজে লাগে এমন কিছু ফাংশনের ব্যবহার শিখবো। আর এর মাঝখানে দেখে নেব কিভাবে Apple ডকুমেন্টেশন দেখে দেখে হঠাৎ যেকোনো অচেনা এলিমেন্ট বা অবজেক্ট নিয়ে কাজ করা যেতে পারে। নিচের উদাহরণ হিসেবে আমরা সেরকম একটি অ্যাপ ধাপে ধাপে করবো যেখানে এই বিষয় গুলোর বাস্তব প্রয়োগ দেখা যাবে। চলুন শুরু করি।

**প্রোজেক্ট ও ইউজার ইন্টারফেস তৈরিঃ** প্রথমে Xcode ওপেন করে একটি নতুন প্রোজেক্ট তৈরি করুন File -> New -> Project… এ ক্লিক করে। এক্ষেত্রে টাইপ হিসেবে সিলেক্ট করুন iOS -> Application -> Single View Application. নিচের মত করে, [![2-2-1](http://nuhil.files.wordpress.com/2014/06/2-2-1.png?w=460)](https://nuhil.files.wordpress.com/2014/06/2-2-1.png) তারপরের স্ক্রিনে এভাবে, [![2-2-2](http://nuhil.files.wordpress.com/2014/06/2-2-2.png?w=460)](https://nuhil.files.wordpress.com/2014/06/2-2-2.png)

প্রোজেক্ট তৈরি হবার পর Xcode এর বাম পাশ থেকে Main.storyboard ফাইলটি সিলেক্ট করুন। ডান পাশে একটিই মাত্র ভিউ ফাইল দেখা যাবে যেহেতু আমাদের অ্যাপ এর টাইপ সিঙ্গেল ভিউ। এরপর Xcode এর ডান পাশের নিচের ইন্টারফেস বিল্ডার প্যানেল থেকে মেইন ভিউ ফাইল বা স্ক্রিনের উপর একটি Label টাইপ এলিমেন্ট নিন, [![Screen Shot 2014-06-19 at 2.11.20 AM](http://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-11-20-am.png)](https://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-11-20-am.png) এবং সেটা সিলেক্ট থাকা অবস্থায় Xcode এর ডান পাশের Attribute Inspector ব্যবহার করে সেটার বিভিন্ন ভিজুয়াল অ্যাপেয়ারেন্স পরিবর্তন করে নিন ইচ্ছা মত। [![Screen Shot 2014-06-19 at 2.12.25 AM](http://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-12-25-am.png)](https://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-12-25-am.png) এরপর আমাদের একমাত্র ভিউ এর উপর একটি Text Field টাইপ এলিমেন্ট নিন এবং সেটারও বিভিন্ন প্রোপার্টি যেমন সাইজ, ফন্ট ইত্যাদি পরিবর্তন করে নিন ডান পাশের Attribute Inspector ব্যবহার করে। এভাবে ঠিক নিচের ছবির মত একটি লে-আউট তৈরি করে নিন। ধরে নিচ্ছি উপরে বলা কথা গুলো বুঝতে পেরেছেন। না বুঝলে এই সেকশনের [১ম চ্যাপ্টার ঘুরে আসুন](http://nuhil.net/2013/10/02/xcode-5-%E0%A6%8F-ios7-%E0%A6%8F%E0%A6%B0-%E0%A6%9C%E0%A6%A8%E0%A7%8D%E0%A6%AF-%E0%A6%AA%E0%A7%8D%E0%A6%B0%E0%A6%A5%E0%A6%AE-%E0%A6%B9%E0%A7%8D%E0%A6%AF%E0%A6%BE%E0%A6%B2%E0%A7%8B-%E0%A6%93%E0%A6%AF/)। [![2-2-3](http://nuhil.files.wordpress.com/2014/06/2-2-3.png?w=460)](https://nuhil.files.wordpress.com/2014/06/2-2-3.png)

**আউটলেট তৈরিঃ** আমাদের ইউজার ইন্টারফেস ডিজাইন হয়ে গেছে দুটি ইউআই UI এলিমেন্ট দিয়ে। এখন এগুলোর জন্য আউটলেট তৈরি করতে হবে যাতে করে আমাদের View Controller কোডের মধ্যে থেকে এগুলোর রেফারেন্স পাওয়া যায়। এজন্য প্রথমে Xcode এর ডান দিকের উপর পাশ থেকে Assistant Editor বাটনটি এনাবেল করে নিন (নিচের ছবিতে 1 চিহ্নিত)। এনাবেল হলে ভিউ ফাইলের পাশেই আরও একটি এরিয়া তৈরি হবে যেখানে ViewController.h ফাইলটি ওপেন অবস্থায় থাকার কথা। ওই ফাইল ওপেন না থাকলে নিচের ছবিতে 2 চিহ্নিত জায়গাটায় ক্লিক করে ViewController.h ফাইলকে ওখানে ওপেন করতে পারেন। এখন কিবোর্ডের Control কি চেপে ধরে আমাদের ভিউ ফাইলের টেক্সট ফিল্ডের উপর থেকে মাউস ক্লিক চেপে ধরে ডান পাশের ফাইলের @interface এর নিচে যেকোনো জায়গায় ছেড়ে দিন। নিচের মত একটি ছোট পপ-আপ আসবে যেখানে এটার প্রোপার্টি টাইপ, নাম ইত্যাদি ঠিক করে দিতে পারবেন। [![2-2-5](http://nuhil.files.wordpress.com/2014/06/2-2-5.png?w=460)](https://nuhil.files.wordpress.com/2014/06/2-2-5.png)

এভাবে সুইচ এলিমেন্ট, ম্যাসেজ দেখানোর লেবেল এবং বাটনটির প্রোপার্টিও ঠিক করে দিন নিচের কোডের মত,

```
// ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UITextField *courseTitle;
@property (strong, nonatomic) IBOutlet UISwitch *continueCourse;
@property (strong, nonatomic) IBOutlet UILabel *messageBox;
@property (strong, nonatomic) IBOutlet UIButton *showButton;

@end
```

**কিবোর্ড হ্যান্ডেলিংঃ** এখন পর্যন্ত ইন্টারফেস এলিমেন্ট গুলো এবং তাদের আউটলেট গুলো রেডি। এই অবস্থায় অ্যাপটি রান করে দেখতে পারেন। যদি সব ঠিক ঠাক ঠাকে তাহলে টেক্সট ফিল্ডটিতে কিছু লেখার জন্য ট্যাপ/ক্লিক করলে সিমুলেটরের কিবোর্ডটী চলে আসবে এবং সেটা ব্যবহার করে কিছু লিখতে পারবেন। কিন্তু লেখা শেষে দেখবেন কিবোর্ডটী সিমুলেটর থেকেই যাচ্ছে। আড়ালে চলে যাচ্ছে না। এখন আমরা কিবোর্ড হ্যান্ডেলিং এর এই সমস্যার একটা সমাধান করবো। এ জন্য প্রথমে ViewController.h ফাইলে textFieldReturn: নামের একটি ফাংশন ডিক্লেয়ার করবো। মূলত এই ফাংশনের মাধ্যমে আমরা কিবোর্ড এর রিটার্ন কি চেপে কিবোর্ডকে হাইড করে ফেলার একটা উপায় প্রয়োগ করবো।

```
// ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UITextField *courseTitle;
@property (strong, nonatomic) IBOutlet UISwitch *continueCourse;
@property (strong, nonatomic) IBOutlet UILabel *messageBox;
@property (strong, nonatomic) IBOutlet UIButton *showButton;

-(IBAction)textFieldReturn:(id)sender;

@end
```

এখন এই ফাংশনটির ইমপ্লিমেন্টেশন লিখবো ViewController.m ফাইলে নিচের মত করে,

```
// ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(IBAction)textFieldReturn:(id)sender
{
    [sender resignFirstResponder];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
```

উপরের textFieldReturn: মেথডের মধ্যে থেকে আমরা যা করছি তা হল, ইভেন্টটি যে অবজেক্ট দারা ট্রিগারড হয়েছে সেই অবজেক্টের resignFirstResponder মেথডকে কল করছি। First Responder হচ্ছে সেই অবজেক্ট যেটা এই মুহূর্তে ইউজারের সাথে ইন্টারঅ্যাক্ট করছে, এ ক্ষেত্রে কিবোর্ডটাই ফার্স্ট রেস্পন্ডার।

এখন textFieldReturn: মেথডটি যাতে সঠিক সময় কল হয় সেজন্য কিছু কাজ করতে হবে। ভিউ কন্ট্রোলার ফাইলের টেক্সট ফিল্ডটিকে সিলেক্ট করুন এবং Xcode এর ডান পাশ থেকে Connection Inspector সিলেক্ট করুন। এরপর Did End on Exit নামের সার্কেল থেকে মাউস ক্লিক করে টেনে এনে ভিউ ফাইলের নিচের View Controller আইকনের উপর ছেড়ে দিন এবং সেখান থেকে textFieldReturn সিলেক্ট করুন। নিচের ছবির মত করে, [![Screen Shot 2014-06-19 at 2.20.22 AM](http://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-20-22-am.png?w=460)](https://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-2-20-22-am.png)

এ অবস্থায় সব সেভ করে যদি অ্যাপটি রান করেন এবং টেক্সট ফিল্ডে কিছু লিখে কিবোর্ডের Return বাটনে ক্লিক/ট্যাপ করেন তাহলে কিবোর্ডটি হাইড হয়ে যাবে, যা আমরা করতে চাচ্ছিলাম। আরও একটা সিচুয়েশনে কিবোর্ড হাইড করা ভালো ইউজার এক্সপেরিএন্স যেমন, টেক্সট ফিল্ড বাদে ভিউ এর অন্য কোথাও ট্যাপ করলেও যাতে কিবোর্ডটি হাইড হয়ে যায়। চলুন সেই ব্যবস্থা করি। এর জন্য আমরা touchesBegan: নামক ইভেন্ট হ্যান্ডেলার মেথডটি ইমপ্লিমেন্ট করবো অর্থাৎ স্ক্রিনে টাচ হলেই এটি সক্রিয় হবে। কিন্তু এই মেথডের মধ্যে আবার এটিও চেক করতে হবে যাতে কেবল মাত্র আমাদের টেক্সট ফিল্ড বাদে অন্য কোথাও টাচ হলেই কিবোর্ড হাইডের মেথড কল করতে পারি। নিচের মত করে মেথডটি ViewController.m ফাইলে লিখে ফেলুন। তাহলে আপডেটেড ফাইলটি হল,

```
// ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(IBAction)textFieldReturn:(id)sender
{
    [sender resignFirstResponder];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    if ([self.courseTitle isFirstResponder] && [touch view] != self.courseTitle) {
        [self.courseTitle resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
```

এখন আবার অ্যাপটি রান করুন এবং টেক্সট ফিল্ডে ক্লিক করুন। স্বভাবতই কিবোর্ড চলে আসবে। এখন হয় কিবোর্ডের return বাটন চাপুন নয়ত স্ক্রিনের যেকোনো জায়গায় ক্লিক/ট্যাপ করুন, কিবোর্ড হাইড হয়ে যাবে।

**ইনপুট আউটপুটঃ** ওকে, এবার আসুন ডাটা ইনপুট এবং সেটা স্ক্রিনে আউটপুটের ব্যবস্থা করা যাক। ViewController.h ফাইলে নতুন একটি ফাংশন ডিক্লেয়ার করুন যাতে আপডেটেড ফাইলটি দেখতে নিচের মত হয়,

```
// ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UITextField *courseTitle;
@property (strong, nonatomic) IBOutlet UISwitch *continueCourse;
@property (strong, nonatomic) IBOutlet UILabel *messageBox;
@property (strong, nonatomic) IBOutlet UIButton *showButton;

-(IBAction)textFieldReturn:(id)sender;
-(IBAction)outputData;

@end
```

এবার এই outputData মেথডটির ইমপ্লিমেন্টেশন লিখে ফেলুন ViewController.m ফাইলে যাতে পুরো ফাইলটি দেখতে নিচের মত হয়,

```
// ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(IBAction)textFieldReturn:(id)sender
{
    [sender resignFirstResponder];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    if ([self.courseTitle isFirstResponder] && [touch view] != self.courseTitle) {
        [self.courseTitle resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

- (IBAction)outputData {
    NSString *isCourseOngoing = (self.continueCourse.on)? @"Ongoing" : @"Not Ongoing";

    self.messageBox.text = [NSString stringWithFormat:@"%@ is %@", self.courseTitle.text, isCourseOngoing];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
```

**এক্সট্রা টিপস (Apple ডকুমেন্টেশন ফলো করা) ঃ** উপরে খেয়াল করুন, outputData মেথডের মধ্যে প্রথমে আমরা isCourseOngoing -এ একটা স্ট্রিং ভ্যালু সেট করছি যেটা নির্ভর করছে continueCourse নামের আউটলেট প্রোপার্টির অর্থাৎ সুইচ এলিমেন্টটির বর্তমান অবস্থার উপর। এখন কথা হচ্ছে এই যে এখানে continueCourse.on লিখে ওই অবজেক্টটির স্ট্যাটাস অ্যাক্সেস করলাম সেটা হঠাৎ আমরা জেনে নিতে পারি কই থেকে?

খেয়াল করলে দেখবেন ওই অবজেক্টটি একটি UISwitch টাইপের। অর্থাৎ এর বিস্তারিত জানা যাবে UISwitch ক্লাসের রেফারেন্স ঘেঁটে দেখলেই। আপনি ঠিকি ধরেছেন, এরকম যেকোনো ক্লাসের রেফারেন্স দেখে নিয়ে সেটার অবজেক্টের উপর আমরা বিভিন্ন অপারেশন করতে পারি। যেমন এই ক্লাসের রেফারেন্স থেকে আমরা জানতে পারি এর কি কি প্রোপার্টি ও মেথড আছে এবং সেরকম একটা প্রোপার্টি হচ্ছে on প্রোপার্টি। [এই লিঙ্কে গেলেই](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISwitch_Class/Reference/Reference.html#//apple_ref/occ/instp/UISwitch/on) দেখতে পারবেন লেখা আছে নিচের মত, [![Screen Shot 2014-06-19 at 1.25.56 AM](http://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-1-25-56-am.png?w=460)](https://nuhil.files.wordpress.com/2014/06/screen-shot-2014-06-19-at-1-25-56-am.png)

অর্থাৎ আমরা continueCourse.on এর মাধ্যমে ওই প্রোপার্টির ভ্যালু অ্যাক্সেস করে ঠিক করতে পারি সুইচটি কি অন নাকি অফ অবস্থায় আছে। তার ঠিক পরেই আমরা messageBox লেবেল এর text প্রোপার্টি হিসেবে একটি ফরম্যাটেড স্ট্রিং সেট করছি; courseTitle এর text প্রোপার্টি এবং isCourseOngoing এর ভ্যালু মিলিয়ে।

এবার শেষ বারের মত অ্যাপটি রান করুন আর টেক্সট ফিল্ডে যেকোনো ভ্যালু এবং তার নিচের সুচটি অন/অফ করে Show Me Back বাটনে ক্লিক করে দেখুন বাটনের ঠিক উপরের জায়গায় আপনার মন মত আউটপুট দেখাচ্ছে কিনা।

> **বইয়ের আপডেট পেতে চোখ রাখুন আমাদের** [**ফ্যান পেজে**](https://www.facebook.com/bangla.objc.swift.ios)

**পরের চ্যাপ্টারঃ** পরের চ্যাপ্টারে অটো লে-আউট নিয়ে বিস্তারিত আলোচনা থাকবে এবং তার উপর ভিত্তি করে একটি পুরো উদাহরণ থাকবে আর তার পর পরই আসবে টেবিল ভিউ নিয়ে চ্যাপ্টার।

Originally Posted [Here](http://nuhil.net/2014/06/19/২-২ঃ-ios-অ্যাপে-ব্যাসিক-ইনপুট/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ios.howtocode.dev/app-development/2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
