مساحة اعلانية

آخر المواضيع

iOS 8 : انشاء لوحة مفاتيح custom باستخدام Swift

iOS 8 : انشاء لوحة مفاتيح  custom باستخدام Swift
iOS 8 : انشاء لوحة مفاتيح  custom باستخدام Swift

نبدأ مع iOS 8, يمكن لتطبيقاتك أن توسيع خاصية custom و المحتويات الى غير تطبيقك و تجعله متاحا للمستخدمين بينما يقومون باستخدام تطبيقات أخرى أو النظام العامل. احدى الطرق المستخدمة لتوسيع النظام العامل هي بانشاء لوحة مفاتيح custom.


سنعرض لك في هذا الدرس كيفية انشاء لوحة المفاتيح custom باستخدام Swift و اضافة التطبيق الجديد APIs. قبل أن نقوم بذلك, سنبحث ما الذي يمكن للوحة المفاتيح الاضافية ان تفعل, و ما الذي لا يمكنها أن تفعله, و ما الذي يجب أن تحصل عليه لتأخذ موافقة App Store.

1. نظرة عامة

تستبدل لوحة المفاتيح custom لوحة مفاتيح النظام للمستخدمين الذين يرغبون  بقدرات مثل طريقة ادخال نص جديد أو القدرة على ادخال نص في لغة ليس بطريقة أخرى مدعوم من قبل النظام العامل.

الوظيفة الأساسية للوحة المفاتيح custom بسيطة, الاستجابة الى النقرات أو الاشارات أو احداث مدخلة جديدة و تزويد نص على شكل كائن NSString  بلا لواحق عند نقطة ادخال النص لكائن النص المدخل الحالي.

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

هنالك عنصران أساسيان للتطوير لكل لوحة مفاتيح custom: الثقة. تمنحك لوحة المفاتيح custom الوصول الى ما يطبعه المستخدم, لذا فالثقة بينك و بين المستخدم هامة جدا. مفتاح "لوحة المفاتيح التالية". التقديم الذي يسمح للمستخدم بالانتقال الى لوحة مفاتيح أخرى هو جزء من واجهة لوحة مفاتيح المستخدم, يجب أن تزود لوحة مفاتيحك بواحد. –دليل برمجة اضافة تطبيق.

في حال أردت فقط اضافة بضعة أزرار للوحة مفاتيح النظام, حينها عليك ان تتفحص وجهات نظر custom عن مدخلات البيانات.

2. المتطلبات و التقييدات

ما الذي لا يمكن للوحة مفاتيح custom أن تفعله

هنالك كائنات ادخال نصية تعد لوحة مفاتيح custom غير مؤهلة لطباعتها. يتضمن ذلك حقول النص المؤمنة لادخال كلمات السر و كائنات الهاتف, مثل حقول رقم الهاتف و تطبيق جهات الاتصال.

ليس لدى لوحة مفاتيح custom وصولا الى المدخلات التي تعرض بشكل هرمي, لا يمكنها التحكم بالمؤشر, و انها غير قادرة على اختيار نص. بالاضافة الى ذلك, لا يمكنها عرض أي شيء فوق الصف الأعلى. لا تعد لوحة مفاتيح النظام محدودة بهذه القيود. على سبيل المثال, فهي تعرض اضافة عندما تنقر مفتاحا لتري المستخدم ما هو المفتاح الذي نقر.

يظهر الخط الأحمر أعلى قيد للوحة مفاتيح custom.

Sandboxing

من خلال الافتراضي, ليس لدى لوحة المفاتيح وصولا للشبكة و لا يمكنها مشاركة ملفات مع تطبيقها المحتوي. من أجل تفعيل هذه القدرات, ضع قيمة مفتاح RequestsOpenAccess في ملف Info.plist  الى نعم. من خلال القيام بذلك يتم مد sandbox للوحة المفاتيح كما هو موصوف في دليل برمجة اضافة التطبيق Apple.

اذا طلبت وصولا مفتوحا, تحصل لوحة مفاتيحك على القدرات التالية, كل واحدة مع مسؤولية مرتبطة بها:

·       الولوج الى خدمات المواقع و قاعة بيانات العناوين, كل واحدة تتطلب اذن المستخدم عند أول دخول

·       خيار استخدام حاوي مشترك مع تطبيق لوحة المفاتيح المحتوي, الذي سيفعل ميزات, مثل التزويد بواجهة مستخدم لادارة مفردات custom في التطبيق المحتوي

·       القدرة على ارسال keystrokes و احداث ادخالات أخرى من أجل معالجة server-side.

·       الوصول الى iCloud, الذي يمكنك استخدمه مثلا لضمان أن اعدادات لوحة المفاتيح و مفردات custom حديثة على كل الاجهزة التي يملكها المستخدم

·       الولوج الى مركز الالعاب و شراء in-app من  خلال التطبيق المحتوى.

·       القدرة على العمل بتطبيقات مدارة في حال صممت لوحة مفاتيحك لتدعم ادارة جهاز الموبايل (MDM)

احرص على قراءة وثيقة Apple تصميم لثقة المستخدم, التي تصف مسؤولياتك احترام و حماية بيانات المستخدم في حال طلبت ولوجا مفتوحا.

3. كيف تعمل

لدينا في الشكل الأساسي تطبيقا يحوي على اضافة لوحة مفاتيح و  UIInputViewController تتحكم بلوحة المفاتيح و تستجيب لأحداث المستخدم.

يحوي قالب لوحة مفاتيح Custom   على أصناف فرعية  لـ UIInputViewController, و التي تعد متحكم المشهد الاولي للوحة مفاتيحك.  دعنا نلقي نظرة على الواجهة لنعرف كيف تعمل.


class UIInputViewController : UIViewController, UITextInputDelegate, NSObjectProtocol {


    var inputView: UIInputView!


    var textDocumentProxy: NSObject! { get }


    func dismissKeyboard()
    func advanceToNextInputMode()


    // This will not provide a complete repository of a language's vocabulary.
    // It is solely intended to supplement existing lexicons.
    func requestSupplementaryLexiconWithCompletion(completionHandler: ((UILexicon!) -> Void)!)
}

    inputView هو المشهد المستخدم للوحة المفاتيح, و هي نفس خاصية المشهد
    طريقة  dismissKeyboard يمكن أن تستدعى فصل لوحة المفاتيح
    advanceToNextInputMode تستخدم للتغيير بين لوحات المفاتيح
    textDocumentProxy هو الكائن الذي ستستخدمه للتفاعل مع المدخلات النصية الحالية


self.textDocumentProxy.insertText("Tuts+") // inserts the string "Tuts+" at the insertion point


self.textDocumentProxy.deleteBackward() // Deletes the character to the left of the insertion point

    تتطابق UIInputViewController مع بروتوكول UITextInputDelegate, مخبرا اياك عندما يتغير النص أو اختيار النص خلال selectionWillChange, selectionDidChange , textWillChange و textDidChangeevents

4. انشاء لوحة مفاتيح حاسبة

دعونا ننشئ لوحة مفاتيح custom لنجعل ذلك محسوسا أكثر الى حد ما. سننشئ لوحة مفاتيح بسيطة  يمكنها التعامل مع المدخلات الرقمية و العمليات البسيطة. سنقوم باستخدام ملف XIB من أجل واجهة تطبيق المستخدم.

خطوة 1: انشاء مشروع جديد

قم بفتح Xcode 6, قم بانشاء تطبيق ذات مشهد فردي و اختر Swift كلغة البرمجة. قم بتسميته  CalculatorKeyboard.

خطوة 2: أضف حقل نصي

قم بفتح Main.storyboard  و اسحب حقل نصي من مكتبة الكائنات. سنستخدم  هذا لفحص لوحة المفاتيح لاحقا. ضع حقل النص في المنتصف  و أضف حدود الشكل الضرورية كما هو موضح بالاسفل.

اذا استدعيت textField.becomeFirstResponder()  في viewDidLoad فان لوحة المفاتيح ستنفتح عندما تبدأ التطبيق.

خطوة 3: أضف اضافة لوحة المفاتيح

اختر ملف المشروع من Project Navigator  (ملاح المشروع) و أضف الهدف الجديد من خلال النقر على زر الاضافة في الاسفل.

اختر اضافة التطبيق على اليسار و اختر عارض لوحة مفاتيح custom و سمه حاسبة (Calculator).

هذا سينشئ مجموعة اسمها حاسبة  (Calculator), تحوي على ملفين KeyboardViewController.swift  و Info.plist.

خطوة 4: التنظيف

افتح KeyboardViewController.swift. لدى عارض لوحة المفاتيح زر واحد مهمته اتاحة المجال للمستخدم التنقل بين لوحات المفاتيح. استبعد الكود من طريقة viewDidLoad.

خطوة 5: انشاء واجهة التطبيق

انقر مباشرة على مجموعة الحاسبة و اختر ملفا جديدا.... اختر قسم واجهة التطبيق على اليسار, و اختر عارض المشهد و الذي يدعى بـ  .Calculator.xib

افتح ملف XIB, في متحري اللواحق على اليسار, ضع الحجم شكل حر و حالة اللوح لا شيء.

قم بوضع عرض المشهد 320 و الارتفاع 160 في متحري الحجم.

اسحب زرا من مكتبة الكائنات للمشهد. في متحري اللواحق, ضع العنوان 1. في متحري الحجم, ضع ارتفاع و عرض الزر 30. حرك الزر الى اعلى الزاوية اليمنى للمشهد حتى تصبح على نفس الخط مع الهوامش.


انسخ الزر من خلال نقر و سحب الزر بينما تضغط على مفتاح الاختيارات. ضع الزر الثاني اسفل الاول.

اختر الازرار من خلال الضغط على Command-A و نسخ المفاتيح. ضع الازرار الجديدة أسفل الزر الاول و الثاني.

قم بتكرير العملية لانشاء عامود اخر من الازرار حتى يصبح لديك أربعة عواميد من الازرار.

ثم اختر العامود الذي على اليسار و قم بانشاء نسخة تكون على نفس مسار الجهة الحدودية اليسرى للمشهد.

ضع عرض الازرار 140 نقطة. استبدل الزر الذي في اعلى اليسار بتصنيف لديه نفس حجم الزر. أعد تسمية الازرار كما هو موضح بالصورة التي في الاسفل.

أضفي على الخلفية لون مائل للزرقة و عين لون خلفية الازرار أبيض مع نسبة لا نفاذية تقدر بـ15%. و من أجل عرض التصنيف, اجعلها سوداء مع نسبة لا نفاذية تقدر بـ15%. ضع حجم النص 18 نقطة لكل كائن واجهة التطبيق و ضع لون النص أبيض. يجب على واجهة التطبيق ان تبدو كهذا:

خطوة 6: تحميل واجهة التطبيق

سنحتاج أولا لانشاء خاصية من أجل تخزين واجهة التطبيق.


class KeyboardViewController: UIInputViewController {
    var calculatorView: UIView!


    ...
}

قم بانشاء طريقة تدعى loadInterface  و  سمها طريقة viewDidLoad  لـ KeyboardViewController.


class KeyboardViewController: UIInputViewController {
    ...


    override func viewDidLoad() {
        super.viewDidLoad()


        loadInterface()
    }


    func loadInterface() {
        // load the nib file
        var calculatorNib = UINib(nibName: "Calculator", bundle: nil)
        // instantiate the view
        calculatorView = calculatorNib.instantiateWithOwner(self, options: nil)[0] as UIView


        // add the interface to the main view
        view.addSubview(calculatorView)


        // copy the background color
        view.backgroundColor = calculatorView.backgroundColor
    }


    ...  
}

خطوة 7: اختبار لوحة المفاتيح

عند هذه المرحلة سيكون بمقدورك أن تفحص لوحة مفاتيحك الجديدة. مع اختيار تخطيط الـ CalculatorKeyboard, قم ببناء و ادارة التطبيق على جهازك. هذا سيضيف لوحة مفاتيح جديدة لجهازك. و لكن قبل ان يمكنك استخدامها, ستحتاج اولا الى تنصيبها.

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

في حال كنت تستخدم محفز iOS, فان لوحة مفاتيح custom يمكن ألا تعمل داخل تطبيقك. لكي ترى لوحة المفاتيح اضغط على الصفحة الرئيسية و افتح Spotlight.

الخطوة 8: لوحة المفاتيح التالية

قم بانشاء خاصية لزر لوحة المفاتيح التالية في صنف KeyboardViewController.


class KeyboardViewController: UIInputViewController {


    @IBOutlet var nextKeyboardButton: UIButton!


    ...
}

افتح Calculator.xib , اختر مالك الملف ((File's Owner, و قم بتغيير صنفها لـ KeyboardViewController في متحري الهوية.

انقر مباشرة على زر لوحة المفاتيح التالية و اربط منفذ للارجاع لمالك الملف.

في طريقة loadInterface, سنضيف نشاط  لزر nextKeyboard كما هو موضح بالاسفل.


class KeyboardViewController: UIInputViewController {
    ...


    func loadInterface() {
        ...


        // This will make the button call advanceToNextInputMode() when tapped
        nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
    }


}

الخطوة 9: عرض الرقم

قم بانشاء خاصية للعرض و اربط منفذ الارجاع في واجهة التطبيق.


class KeyboardViewController: UIInputViewController {


    @IBOutlet var display: UILabel!


    ...
}

قم بانشاء طريقة تدعى clearDisplay و استدعها في طريقة viewDidLoad بعد استدعاء loadInterface. يجب على العرض أن يظهر 0 عندما تفتح لوحة المفاتيح.


class KeyboardViewController: UIInputViewController {
    ...
 

    override func viewDidLoad() {
        super.viewDidLoad()
     

        loadInterface()
        clearDisplay()
    }
 

    ...
 

    @IBAction func clearDisplay() {
        display.text = "0"
    }
}

اربط زر C حدث touch up inside مع طريقة clearDisplay  في باني الواجهة.

الخطوة 10: مدخلال الارقام

حان الوقت للتعامل مع مدخلات الارقام. عندما تفتح لوحة المفاتيح ستظهر 0 على العارض. اذا نقرت على مفتاح رقم ما, يجب أن تستبدل العارض بذلك الرقم. قم بانشاء خاصية تدعى shouldClearDisplayBeforeInserting  لانشاء هذا الازرار الارقام لوك.

قم بانشاء طريقة تدعى didTapNumber  و اربطها في باني الواجهة بكل أزرار الارقام لحدث touch up inside. تستخدم الطريقة titleLabel  للزر لتحدد أي رقم تم نقره.

class KeyboardViewController: UIInputViewController {
    var shouldClearDisplayBeforeInserting = true


    ...


    @IBAction func didTapNumber(number: UIButton) {
        if shouldClearDisplayBeforeInserting {
            display.text = ""
            shouldClearDisplayBeforeInserting = false
        }


        if var numberAsString = number.titleLabel?.text {
            var numberAsNSString = numberAsString as NSString
            if var oldDisplay = display?.text! {
                display.text = "\(oldDisplay)\(numberAsNSString.intValue)"
            } else {
                display.text = "\(numberAsNSString.intValue)"
            }
        }
    }
}

قم بتحديث طريقة clearDisplay  كما هو موضح بالاسفل.

class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func clearDisplay() {
        display.text = "0"
        shouldClearDisplayBeforeInserting = true
    }
}

تعد كود لوحة المفاتيح هدفا مختلفا عن تطبيقك. و لذلك فان السجلات الصحيحة لا تعد مرئية. لرؤية جذور هدف الحاسبة, افتح جذر النظام من محفز  Ios.

الخطوة 11: مدخلات النقطة

يجب على الزر الذي عليه ادخال النقطة ان يضيف نقطة الى العارض, و لكن هذا فقط اذا لم يكن هنالك نقطة موجودة بعد.


class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func didTapDot() {
        if let input = display?.text {
            var hasDot = false
            for ch in input.unicodeScalars {
                if ch == "." {
                    hasDot = true
                    break
                }
            }
            if hasDot == false {
                display.text = "\(input)."
            }
        }
    }
}

الخطوة 12: ادخال نص

يجب على النص الذي عليه ادخال نص أن يضيف نص عرض الحاسبة الى نقطة الادخال. لفعل ذلك سنستخدم خاصية  textDocumentProxy كما هو موضح بالاسفل.




class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func didTapInsert() {
        var proxy = textDocumentProxy as UITextDocumentProxy


        if let input = display?.text as String? {
            proxy.insertText(input)
        }
    }
}

الخطوة 13: التعامل مع العمليات

لاننا نقوم بانشاء لوحة مفاتيح بسيطة لا تدعم أشجار التعبير,  1 + 2 * 3ستساوي 9, فاننا سوف نستخدم نموذج أبسط حيث يكون لدى الحاسبة فتحة ذاكرة داخلية نقوم بتطبيق العمليات عليها.

دعونا نأخذ مدخلا بسيطا كم أجل فهم كيفيو عمل نظام الحاسبة:

    ينقر المستخدم 1, يري العارض تغييرا من 0 الى 1
    ينقر المستخدم +, يجب على الحاسبة أن تتذكر أن تضيف الرقم المدخل التالي الى 1
    ينقر المستخدم 2, يجب على العارض أن يتغير من 1 الى 2
    ينقر المستخدم *, يجب أن تتغير كلا من العارض و الذاكرة الداخلية الى 3, يجب على الحاسبة ان تتذكر أن تضاعف الذاكرة الداخلية مع الرقم المدخل التالي
    ينقر المستخدم 3, يجب أن يبقى العارض 3
    ينقر المستخدم =, يجب على الحاسبة أن تطبق العملية الاخيرة  و يجب على العارض أن يتغير الى 9

ملا حظات:

    يجب على الحاسبة أن تتذكر العملية التالية التي يجب تطبيقها
    بعد ادخال رقم اذا تم تنفيذ عملية أو يساوي, فانه يجب على الحاسبة  أن تطبق اخر عملية تذكرها
    اذا نفذ المستخدم عمليتان أو اكثر من دون ادخال رقم, يجب على الحاسبة أن تتذكر اخر واحدة
    بعد أن يتم تطبيق عملية, يجب على العارض أن يحدث النتيجة
    يعد أن يتم عرض النتيجة,  يجب على العارض أن يوضح قبل كتابة رقم اخر

من أجل انشاء الحاسبة, سنحتاج ما يلي:

    خاصية internalMemory  التي تخزن النتيجة الؤقتة
    خاصية تخزن nextOperation
    واحدة أخرى لتذكر فيما اذا يجب أن تطبق nextOperation  بعد ان يتم تنفيذ العملية



enum Operation {
    case Addition
    case Multiplication
    case Subtraction
    case Division
    case None
}


class KeyboardViewController: UIInputViewController {
    var internalMemory = 0.0
    var nextOperation = Operation.None
    var shouldCompute = false


    ...
}

قم بانشاء طريقة تدعى didTapOperation  و اربطها بأزرار عملية حدث touch up inside في باني الواجهة. ستستخدم الطريقة عنوان الزر لتحديد اي عملية يجب تنفيذها.


class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func didTapOperation(operation: UIButton) {
        if shouldCompute {
            computeLastOperation()
        }


        if var op = operation.titleLabel?.text {
            switch op {
                case "+":
                    nextOperation = Operation.Addition
                case "-":
                    nextOperation = Operation.Subtraction
                case "X":
                    nextOperation = Operation.Multiplication
                case "%":
                    nextOperation = Operation.Division
                default:
                    nextOperation = Operation.None
            }
        }
    }
}

قم بانشاء طريقة computeLastOperation .


class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func computeLastOperation() {
        // remember not to compute if another operation is pressed without inputing another number first
        shouldCompute = false


        if var input = display?.text {
            var inputAsDouble = (input as NSString).doubleValue
            var result = 0.0


            // apply the operation
            switch nextOperation {
            case .Addition:
                result = internalMemory + inputAsDouble
            case .Subtraction:
                result = internalMemory - inputAsDouble
            case .Multiplication:
                result = internalMemory * inputAsDouble
            case .Division:
                result = internalMemory / inputAsDouble
            default:
                result = 0.0
            }


            nextOperation = Operation.None


            var output = "\(result)"


            // if the result is an integer don't show the decimal point
            if output.hasSuffix(".0") {
                output = "\(Int(result))"
            }


            // truncatingg to last five digits
            var components = output.componentsSeparatedByString(".")
            if components.count >= 2 {
                var beforePoint = components[0]
                var afterPoint = components[1]
                if afterPoint.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 5 {
                    let index: String.Index = advance(afterPoint.startIndex, 5)
                    afterPoint = afterPoint.substringToIndex(index)
                }
                output = beforePoint + "." + afterPoint
            }




            // update the display
            display.text = output


            // save the result
            internalMemory = result


            // remember to clear the display before inserting a new number
            shouldClearDisplayBeforeInserting = true
        }
    }
}

قم بتحديث clearDisplayMethod  كما هو موضح بالاسفل. عندما يبدأ المستخدم بكتابة أن تعين 0  و يجب أن تكون nextOperationd  اضافة.  بتلك الطريقة, و بعد أن يدخل المستخدم الرقم الاول و ينفذ على عملية ما, ستتذكر الحاسبة الرقم المدخل.


class KeyboardViewController: UIInputViewController {
    ...


    @IBAction func clearDisplay() {
        display.text = "0"
        internalMemory = 0
        nextOperation = Operation.Addition
        shouldClearDisplayBeforeInserting = true
    }
}

الخطوة 14: اللمسات الاخيرة

دعونا نستخدم لاحقة الاعلان IBInspectable لاضافة زاوية نصف قطر الى الزرار و العرض. اولا, قم بانشاء صنف فرعي لـ UIButton  و UILabel.


class RoundButton: UIButton {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }
}


class RoundLabel: UILabel {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }
}

في باني الواجهة, اختر لازرار و غير صنفهم الى صنف RoundButton  في متحري الهوية. في متحري اللواحق, يجب أن ترى  لاحقة نصف قطر الزاوية الجديدة.

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

الخاتمة

يجب أن تكون قادرا الان على انشاء لوحة مفاتيح custom في iOS باستخدام  اضافة التطبيق APIs.  تذكر أن على كل لوحة مفاتيح custom أن يكون لديها طريقة للتنقل الى لوحة المفاتيح التالية و ان لوحة المفاتيح الخاصة بك غير قادرة على الاتصال بالانترنت, الولوج الى خدمات المواقع, أو التحدث مع تطبيقها المحتوي من قبل الافتراضي و لكن يجب أن تطلب هذه الامكانيات.

سيستخدم النظام لوحة مفاتيح افتراضية من أجل تأمين الحقول, مثل كلمة الرقم و حقول أرقتم الهاتف. لا تنس ان كود لوحة مفاتيح custom تعيش في هدف منفصل. و بسبب ذلك فان السجلات الصحيحة غير مرئية. من أجل رؤيتهم, افتح سجل النظام من محفز iOS.

الكــاتــب

    • مشاركة

ليست هناك تعليقات:

جميع الحقوق محفوظة لــ الشبح للمعلوميات 2019 ©