• UITableViewController
  • UINavigationController
  • navigationItem
  • UITableView structure
  • UIImagePickerView

SettingsController.swift

in viewDidLoad()
navigationItem.title = "Settings"
navigationController?.navigationBar.prefersLargeTitles = true

UINavigationController

A container view controller that defines a stack-based scheme for navigating hierarchical content.

What is a container view?

Documentation

    @objc func handleSettings() {
        let settingsController = SettingsController()
        let navController = UINavigationController(rootViewController: settingsController)
        present(settingsController, animated: true)
    }

set up navigationItem

    fileprivate func setupNavigationItems() {
        navigationItem.title = "Settings"
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel))
        navigationItem.rightBarButtonItems = [
            UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(handleCancel)),
            UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleCancel))
        ]
    }

How to remove seperate lines

give a blank UIView to tableFooterView

tableView.tableFooterView = UIView()

UITableView Structure

TableView header

in override

  • viewforheader : set UIView of header

  • heightforheader : set height of header

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = UIView()
        header.backgroundColor = .blue
        return header
    }
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 300
    }

creating UIButton with lazy var

use lazy var because of declaration problem

    lazy var image1Button = createButton()
    lazy var image2Button = createButton()
    lazy var image3Button = createButton()
    
    func createButton() -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle("select photo", for: .normal)
        return button
    }

tableView viewForHeader

header section

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        ...
        header.addSubview(image1Button)
        return header
    }
        let header = UIView()
        header.addSubview(image1Button)
        let padding: CGFloat = 16
        image1Button.anchor(top: header.topAnchor, leading: header.leadingAnchor, bottom: header.bottomAnchor, trailing: nil, padding: UIEdgeInsets.init(top: padding, left: padding, bottom: padding, right: 0))
        image1Button.widthAnchor.constraint(equalTo: header.widthAnchor, multiplier: 0.45).isActive = true

just set up header’s backgroundColor as some color to check where it is. give constratins to button in header

StackView

        let stackView = UIStackView(arrangedSubviews: [image2Button, image3Button])
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.spacing = padding
        
        header.addSubview(stackView)
        stackView.anchor(top: header.topAnchor, leading: image1Button.trailingAnchor, bottom: header.bottomAnchor, trailing: header.trailingAnchor, padding: .init(top: padding, left: padding, bottom: padding, right: padding))

imagePickerView

How does handleSelectPhoto’s parameter work??

beverytime we tap each button, button parameter pass button’s memory address I guess when we doesn’t specify parameter using the function, object that invokes the function would be passed as a parameter of the function.

    @objc fileprivate func handleSelectPhoto(button: UIButton) {
        print("Select photo with button", button)
        let imagePicker = CustomImagePickerController()
        imagePicker.delegate = self
        present(imagePicker, animated: true)
    }

imagePicker.delegate

Summary

The image picker’s delegate object.

Discussion

The delegate receives notifications when the user picks an image or movie, or exits the picker interface. The delegate also decides when to dismiss the picker interface, so you must provide a delegate to use a picker. If this property is nil, the picker is dismissed immediately if you try to show it.

For information about the methods you can implement for your delegate object, see UIImagePickerControllerDelegate.

imagePicker.delegate = self

self is SettingsController

that code above doesn’t compile until we specify two protocols below.

UIImagePickerControllerDelegate, UINavigationControllerDelegate

this function will be invoked when we pick a photo in UIImagePickerVIewController

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        let selectedImage = info[.originalImage] as? UIImage
        // how do I set the image on my buttons when I select a photo?
        dismiss(animated: true)
    }

how do I set the image on my buttons when I select a photo?

CustomImagePickerController

We can extend UIImagePickerController as CustomImagePickerController. It would have a UIButton property

class CustomImagePickerController: UIImagePickerController {
    var imageButton: UIButton?
}

Every time we invoke handleSelectPhoto(button: UIButton), CustomImagePickerController is generated. we can set the property(UIButton) from parameter

    @objc fileprivate func handleSelectPhoto(button: UIButton) {
        // imagePicker
        let imagePicker = CustomImagePickerController()
        imagePicker.delegate = self
        imagePicker.imageButton = button
        present(imagePicker, animated: true)
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        let selectedImage = info[.originalImage] as? UIImage
        ...
        dismiss(animated: true)
    }

Do typecasting to use customImagePickerController in imagePickerController function

let imageButton = (picker as? CustomImagePickerController)?.imageButton
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        let selectedImage = info[.originalImage] as? UIImage
        // how do I set the image on my buttons when I select a photo?
        imageButton?.setImage(selectedImage?.withRenderingMode(.alwaysOriginal), for: .normal)
        dismiss(animated: true)
    }
        let selectedImage = info[.originalImage] as? UIImage
        // how do I set the image on my buttons when I select a photo?
        let imageButton = (picker as? CustomImagePickerController)?.imageButton
        imageButton?.setImage(selectedImage?.withRenderingMode(.alwaysOriginal), for: .normal)

Don’t forget change WithRenderwingMode whenever we set UIView’s image

태그: ,

카테고리:

업데이트:

댓글남기기