なんとかするから、なんとかなる

エンジニア関係のことを書きます

iOS UITextField How to dismiss the keyboard when user tap a retrun key.

Introduction

This article show you that how to dismiss the keyboard when user tap a return key on UITextField of iOS.

In fact, this way shows on the iOS SDK document. I've never knew it.

Solution

  1. Adapt the UITextFieldDelegate on your ViewController

  2. Assign the self in the textField's delegate

  3. Implement the textFieldShouldReturn: method

  4. On textFieldShouldReturn: method, call the resignFirstResponder()

  5. And return the value true or false

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet var textField : UITextField!
    override func viewDidLoad() {
        self.textField.delegate = self 
    }

    func textFieldShouldReturn(textField: UITextField!) -> Bool {
        self.view.endEditing(true)
        return false
    }
}

Detail

textFieldShouldReturn:

This textFieldShouldReturn: method is called when user tap the return button on the keyboard.

If you want to do its default behavior for the return button, you need to return true otherwise false.

In this case, to dismiss the keyboard, it wouldn't be a problem that which value is returned.

resignFirstResponder

First Responder means like a focus.

So, when this method call, the focus will resign from the UITextField's instance.

The keyboard will dismiss when the focus would out.

ReferenceURL

iOS UITableView deleteRows(at:with:) was crashed

Introdution

UITableView is one of the most popular UI system in iOS developer.

But, sometimes this UI system make us annoying.

In this time, when I try to delete the UITableViewCell from swipe or delete button, it would be crashed.

So, this article introduce how to handle this issue.

Probrem

When I wrote the code as below, it will be crashed.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    guard editingStyle == .delete else { return }

    self.tableView.deleteRows(at: [indexPath], with: .fade) // Crashed
    
    // myArray is a DataSource to the tableView
    self.myArray.remove(at: indexPath.row)

An Error message said me as below.

 *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.54.4/UITableView.m:2012

Solution

After resolved the problem, it was simply mistake.

So, the deleteRow(at:with:) need to call after the datasource was changed.

The true code is below, it was working!

Developer need to take case of this kind of problem.

So, if the DataSource's remove method was failed, it will cause the same problem.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    guard editingStyle == .delete else { return }

    // myArray is a DataSource to the tableView
    self.myArray.remove(at: indexPath.row)

    self.tableView.deleteRows(at: [indexPath], with: .fade) // Working!

Extra

The beginUpdates() and endUpdates() is need to call when the deleteRow(at:with:) would be working in the animation block.

So in this case, it's not need to call them.

Reference URL

https://developer.apple.com/documentation/uikit/uitableview/1614960-deleterows

iOS It’s difficult to animate UIView by themselves when it appeared.

Introduction

This article explains its difficult to animate an UIView by themselves when it appeared.

Conclusion

There two solution for the problem. • Call some animation start method by UIViewController • Observe the didBecomeActive event from a notification.

Detail

UIView have some lifecycle methods and drawing methods as you know.

I tried to set a method that’ll start an animation for the UIView.

But, the methods like a didMoveToWindow etc. is called multi times.

And other method like layoutSubview(), drawRect: is not called when an app come back from background.

If I set an animation with options=.repeat, the animation would be stopped when the app would go to background or execute some segue.

It’s not impossible to set the animation again when it come from the segue.

But, but it’s so difficult to set the animation again when the app come back from background.

That’s why I put my conclusions.

iOS How to detect the instance is inheritance of some class or not.

Intoroduction

This are article shows how to detect the instance is inheritance of some class or not.

Solution

if someInstane is SomeClass {
    // The Instance is inheritance of some class.
} else {
    // Instance is not inheritance of some class.
}

iOS How to detect an user interacion while animating

Introduction

This article shows how to detect an user interaction while animating on UIView or UIbutton or etc.

Solution

Set the ".allowUserIntercation" properties in option at UIView.animate method.

UIView.animate(withDuration: 1.0, 
    delay: 0,
    options: [.allowUserInteraction],
    animations: {
    self.view.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
}, completion: nil)    }

Reference URL

iOS UITableViewCellで選択されたCellをもとに戻す

English version below.

はじめに

選択されたCellをもとに戻す。よくやることですが、恥ずかしながら勘違いして覚えていたので備忘録。

解決方法

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}

おまけ

はじめに次のようにして非選択すると覚えていました。

let cell = tableView.cellForRow(at: indexPath)
cell.(SOMETHING)

当然ながら(SOMETHING)メソッドは見つかりませんでした;) cellに対して、非選択にするわけではないので注意しましょう。

iOS How to deselect a cell which was tapped by user.

Introduction

This article shows how to deselect an cell when user tapped it.

Solution

It's a easy way to do it.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}

At first, I tried to get the cell which was tapped as below.

let cell = tableView.cellForRow(at: indexPath)
cell.(SOMETHING)

But, I couldn't find (SOMETHING) method. That's because I wrote this article ;)