tintColor란 무엇이며 image renderingMode 살펴보기

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


tintColor

tintColor란 시각적으로 화면 상의 어떤 요소가 현재 활성화되었는지를 보여주는 요소

예로들어 NavigationBar의 아이템의 refresh 버튼이나 back 버튼을 누르면 단순히 눌리고 끝나는 것이 아니라 눌려졌을때 흰색으로 살짝 변했다가 다시 원래의 색으로 돌아오는 것이 그 예시이다. 이런 효과를 가능하게 하는것이 바로 tintColor이다. 기본적으로 tintColor는 UIView의 프로퍼티로 존재하기에 UIView를 상속받는뷰들은 모두 tintColor를 적용시킬 수 있다!

따라서 view에 tintColor를 사용하기 위해서는 약간의 방법이 필요한데
그 방법은 바로 image의 renderingMode를 .alwaysTemplate으로 바꿔야 하는 것이다.

renderingMode

UIImage의 renderingMode코드를 살펴보면 아래와 같이 세가지 옵션이 있다.

@available(iOS 7.0, *)
    public enum RenderingMode : Int {


        case automatic = 0 // Use the default rendering mode for the context where the image is used


        case alwaysOriginal = 1 // Always draw the original image, without treating it as a template

        case alwaysTemplate = 2 // Always draw the image as a template image, ignoring its color information
    }

1. automatic

이미지 렌더링 모드 중에서 automatic은 default 값이다.
뷰 상에서는 제대로 나오지만 탭바에서 이미지가 불투명한 부분을 틴트컬러로 보이게 한다.

let image = UIImage(named: "")?.withRenderingMode(.automatic)

2. alwaysOriginal

원본 이미지에서 컬러정보가 모두 보이는 것으로 말 그대로 원본의 색상 정보 그대로 이미지에 보여진다.

let image = UIImage(named: "")?.withRenderingMode(.alwaysOriginal)

3. alwaysTemplate

원본 이미지에서 컬러 정보가 모두 제거되고 불투명한 부분을 틴트컬러로 보이게 한다.
즉, 원본 이미지가 가지고 있는 컬러정보는 사라지고 내가 지정한 tintColor로 이미지의 색상이 보여지는 것을 의미한다.

let button = UIButton()
button.setImage(UIImage(named: "")?.withRenderingMode(.alwaysTemplate), for: .normal)
button.tintColor = UIColor.red

이런식으로 코드가 짜여진다면 버튼에 들어가는 이미지의 원본 색상은 사라지고 내가 지정한 tintColor인 red 색상이 버튼 이미지의 색상이 될 것이다.

UIView의 ContentMode 정리

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


ContentMode

UIImageView안에 이미지를 삽입하려하다보면 각각의 이미지를 어떤 비율로 넣을 지 정해주어야 하는데,
이때 UIView에서 ContentMode로 정해줄 수 있다.

기본적으로 top, bottom, left, right 등이 존재하지만 이 속성들은 직관적으로 바로 느껴질 것이다. > 위, 아래, 왼쪽, 오른쪽
외에 많이 사용하지만 헷갈리는 scaleToFill, scaleAspectFit, scaleAspectFill 이 세가지를 정리해보자.

scaleToFill

콘텐츠의 비율을 변경하여 View 크기에 맞게 확장하는 옵션

scaleAspectFit

콘텐츠의 비율을 유지하며 View의 크기에 맞게 확장하는 옵션으로 남는 영역은 투명하다

scaleAspectFill

콘텐츠의 비율을 유지하며 View의 크기에 빈 영역 없이 확장하는 옵션으로 일부 내용이 사라질 가능성이 있다.

  • aspect: 비율 유지
  • fill: 화면에 빈틈없이 꽉차게
  • fit: 화면에 딱 맞게

PickerView가 있는 Alert 창 만들기

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


PickerView가 있는 Alert 창 만들기

해당 블로그를 참고하여 만들어보았습니다. > 참고한 블로그

UIAlertController

addAction에 tableView.reloadData()가 들어가는 이유는 해당 버튼이 tableview cell에 들어가있기 때문이다.

  1. 버튼을 누르면 개월수를 체크하는 pickerView가 뜬다.
  2. 원하는 개월수를 선택 후 확인 버튼을 누르면 label에 내가 선택한 개월수가 나온다.
class ViewController: UIViewController {

    let pickerList = ["2개월", "3개월", "4개월", "5개월", "6개월", "7개월", "8개월", "9개월", "10개월", "11개월", "12개월"]
    var pickerView = UIPickerView()
    var typeValue = String()

    @IBAction func touchDateSelectBtn(_ sender: UIButton) {
        let alert = UIAlertController(title: "예상 프로젝트 기간", message: "\n\n\n\n\n\n", preferredStyle: .alert)
        alert.isModalInPopover = true
        let pickerFrame = UIPickerView(frame: CGRect(x: 5, y: 20, width: 250, height: 140))
        alert.view.addSubview(pickerFrame)
        pickerFrame.delegate = self
        pickerFrame.dataSource = self

        alert.addAction(UIAlertAction(title: "취소", style: .default, handler: nil))
        alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { (UIAlertAction) in
            print("\(self.typeValue)")
            self.tableView.reloadData()
        }))
        self.present(alert, animated: true, completion: nil)

    }

UIPickerViewDelegate, UIPickerViewDataSource

extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return self.pickerList.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerList[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if row == 0 {
            typeValue = "2개월"
        } else if row == 1 {
            typeValue = "3개월"
        } else if row == 2 {
            typeValue = "4개월"
        } else if row == 3 {
            typeValue = "5개월"
        } else if row == 4 {
            typeValue = "6개월"
        } else if row == 5 {
            typeValue = "7개월"
        } else if row == 6 {
            typeValue = "8개월"
        } else if row == 7 {
            typeValue = "9개월"
        } else if row == 8 {
            typeValue = "10개월"
        } else if row == 9 {
            typeValue = "11개월"
        } else if row == 10 {
            typeValue = "12개월"
        }
    }
}

UITableView

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "DateSelect") as! DateSelectTableViewCell
    cell.pickerLbl.text = self.typeValue
    return cell

iOS tableview cell에서 WKWebView 사용해보기

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


WKWebView 사용해보기

현재 만들고 있는 프로젝트의 골격은 이렇다.

  1. tap page Controller를 사용
  2. 각 페이지는 tableview로 구성되어있으며
  3. 웹뷰를 가져오는 공간은 tableview cell 안에 존재한다.

참고한 블로그는 요기이며 이를 내 플젝에 맞게 재 구성하였다.

시작해보기

이를 시작하기 위해 나는 아래와 같은 셋팅을 했다.

  1. xib 커스텀 셀 제작 > 그렇다면 당연히 tableview cell 파일이 존재할 것이며
  2. MainTableVC에서 tableview에 대한 설정을 해주었다.

MainTableVC

import UIKit
import WebKit

class MainTableVC: UIViewController {
  @IBOutlet weak var tableView: UITableView!

  override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.separatorStyle = .none
        self.tableView.showsHorizontalScrollIndicator = false

        // 커스텀 셀을 가져오는 부분
        self.tableView.register(UINib(nibName: "Cell", bundle: nil), forCellReuseIdentifier: "")
    }
}

extension MainTableVC: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "셀 identifier") as! TableViewCell
        let registerCellView = cell.setWebView(rootVC: self, frame: self.view.frame)
        registerCellView.uiDelegate = self
        registerCellView.navigationDelegate = self
        cell.addSubview(registerCellView)
        return cell

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}

extension MainTableVC: WKUIDelegate, WKNavigationDelegate {      
    //모달창 닫힐때 앱 종료현상 방지
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // alert
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "확인", style: .default, handler: {(action) in completionHandler()}))
        self.present(alertController, animated: true, completion: nil)
    }

    // confirm
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "확인", style: .default, handler: {(action) in completionHandler(true)}))
        alertController.addAction((UIAlertAction(title: "취소", style: .default, handler: { (action) in completionHandler(false)})))
        self.present(alertController, animated: true, completion: nil)
    }

    // href="_blank" 처리
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }
}

셀 이름을 적어줘야하는 부분(withIdentifier)엔 각자가 지정해준 identifier를 적어주면 됩니다
이름을 잘 적었는지 확인하는것을 필! 수!

cell 파일

import UIKit
import WebKit

class TableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func setWebView(rootVC: UIViewController, frame: CGRect) -> WKWebView {
        let webView = WKWebView(frame: self.contentView.frame)

        let url = URL(string: "가져올 웹 페이지 주소")
        let request = URLRequest(url: url!)

        webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
        webView.load(request)

        return webView
    }
}

해당 cell파일에서 만든 setWebView 함수를 MainTableVC에서 사용하고 있음을 확인해주세요

이렇게 테이블 뷰 셀에 웹 페이지를 가져오는 것을 해보았습니다:)
잘못된 부분이 있었거나, 더 좋은 방법이 있다면 아래 댓글에 꼭꼭 남겨주세요!

iOS Tap Page Controller 사용방법

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


Tap Page Controller

정리중입니다.

import UIKit
import SnapKit

enum ProjectType {
    case Coupon
    case Identifier
    case Resister
}

class MainVC: UIViewController, MainVCDelegate {

    @IBOutlet weak var containerView: UIView!

    var tableType: ProjectType = .Coupon

    weak var tabPageViewController: TabPageViewController!

    var couponView = MainTableVC.instance()
    var identifierView = MainTableVC.instance()
    var resisterView = MainTableVC.instance()

    var couponList = Array<ModelProject>()
    var identifierList = Array<ModelProject>()
    var resisterList = Array<ModelProject>()


    override func viewDidLoad() {
        super.viewDidLoad()

        tabPageViewController = TabPageViewController.create()

        couponView.tabHeight = tabPageViewController.option.tabHeight
        couponView.delegate = self
        couponView.projectType = .Coupon

        identifierView.tabHeight = tabPageViewController.option.tabHeight
        identifierView.delegate = self
        identifierView.projectType = .Identifier

        resisterView.tabHeight = tabPageViewController.option.tabHeight
        resisterView.delegate = self
        resisterView.projectType = .Resister

        tabPageViewController.tabItems = [(couponView, "쿠폰번호"), (identifierView, "아이디등록"), (resisterView, "쿠폰등록")]

        tabPageViewController.option.fontSize = 14
        tabPageViewController.option.tabHeight = 38
        tabPageViewController.option.currentColor = UIColor.black
//        tabPageViewController.option.defaultColor = UIColor(named: "DDDDDD")!
        tabPageViewController.option.defaultColor = UIColor.gray
        tabPageViewController.option.currentBarHeight = 3

        self.view.addSubview(tabPageViewController.view)
        self.addChild(tabPageViewController)
        self.containerView.addSubview(tabPageViewController.view)
        tabPageViewController.view.snp.makeConstraints {(make) in
            make.top.bottom.leading.trailing.equalTo(self.containerView)
        }

        tabPageViewController.didMove(toParent: self)
    }
}