728x90
반응형


사용자에게 경고를 보여주거나 다시 한번 되물을때 Alert 기능을 사용합니다.


iOS에서도 간단하게 Alert 창을 구현할 수 있도록 지원을 하고 있는데요.


UIAlertController를 사용하여 만들어 보겠습니다.








프로젝트를 하나 만들어서 Storyboard 의 UIViewController에 버튼 2개를 만들었습니다.


Alert 과 ActionSheet 라는 버튼을 만들어 주었습니다.


Alert 버튼과 ActionSheet 버튼을 alertAction이라는 함수로 연결해주었습니다.







    @IBAction func alertAction(_ sender: UIButton) {
        if sender.titleLabel?.text == "Alert" {
            showAlert(style: .alert)
        } else {
            showAlert(style: .actionSheet)
        }
    }
cs


UIAlertController는 preferredStyle에 따라 Alert이 다르게 표현됩니다.

버튼 title이 Alert이면 style을 alert으로 정하고 아니면 actionSheet로 정해주었습니다.


style만 다르고 나머지 부분은 동일하기 때문에 showAlert이라는 함수를 만들어 주었습니다.







    func showAlert(style: UIAlertController.Style) {
        let alert = UIAlertController(title: "알림", message: "내용", preferredStyle: style)
        let success = UIAlertAction(title: "확인", style: .default) { (action) in
            print("확인")
        }
        
        let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil)
        let destructive = UIAlertAction(title: "삭제", style: .destructive)
        
        alert.addAction(success)
        alert.addAction(cancel)
        alert.addAction(destructive)
        
        self.present(alert, animated: true, completion: nil)
    }
cs


UIAlertController를 생성해주고 각 액션을 추가해주었고


각 기능을 하는 UIAlertAction 을 만들어 style을 다르게 설정하였습니다.


default : 일반적인 액션 버튼 


cancel : actionSheet로 표현 되거나 alertAction이 많아지면 맨 아래에 위치하게 됩니다.


estructive : 글자를 Red 색으로 표현해준다.





Alert 버튼 클릭 - 액션이 3개 이상





Alert 버튼 클릭 - 액션이 2개 이하







ActionSheet 버튼 클릭







각 UIAlertAction의 handler 에서 기능을 처리 하면 됩니다.


이렇게 간단하게 UIAlertController에 대해서 알아보았습니다.


728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

[XCode] Cocoapod Build Error  (0) 2019.12.20
[XCode 11] iOS 13 다크모드 해제  (0) 2019.12.09
Swift 4 TableView Section  (0) 2019.03.04
Swift 4 UIRefreshControl  (0) 2019.03.04
Swift 4 TableViewCell SwipeAction  (0) 2019.02.21
728x90
반응형


iPhone의 연락처 앱처럼 구분을 하여 목록을 보여주고 싶을 때가 있습니다.


블로그나 유튜브를 찾아봐도 TableView의 Section 구분만 나오는게 아닌


특정 기능까지 포함해서 나오기에 복잡해서 어려움도 많았습니다.


딱! 간단하게 TableView Section 처리하는 방법을 알아보겠습니다.







Storyboard에서 UIViewController에 TableView와 TableViewCell 을 추가해줍니다.


TableViewCell의 Attributes Inspactor 로 들어가


Identifier 를 'CellList' 라고 정해주었습니다.


이제 Swift 코드로 들어가보겠습니다.






import UIKit
 
class ViewController: UIViewController {
 
    @IBOutlet weak var tableView: UITableView!
    
    // 임의 데이터 넣기
    var items: [String= ["Apple""Facebook""Google""Kakao""Naver""NcSoft""Github"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
    }
}
cs


Storyboard의 TableView를 @IBOutlet 변수로 연결해주었고


tableVIew의 delegate, dataSource 를 'self'로 지정해 주었습니다.






extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    // Section count
    public func numberOfSections(in tableView: UITableView) -> Int {
        return Array(Set(self.items.map{ $0.first! })).count
    }
    
    // Section의 title
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int-> String? {
        return String(Array(Set(self.items.map{ $0.first! })).sorted()[section])
    }
    
    // row 의 data 대입
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[indexPath.section]
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellList"for: indexPath)
        cell.textLabel?.text = self.items.filter{ $0.first == charactor }[indexPath.row]
        return cell
    }
    
    // Section의 Row count
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int-> Int {
        let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[section]
        return self.items.filter{ $0.first! == charactor }.count
    }
}
cs


ViewController 를 확장하여 TableView 프로토콜을 준수해 함수를 정의하였습니다.


각각 설명을 하겠습니다.





1. Section의 count를 return 합니다.


public func numberOfSections(in tableView: UITableView) -> Int
cs

return Array(Set(self.items.map{ $0.first! })).count
cs

items 라는 array를 map{ $0.first! } 하면 $0로 각각 한개씩 담겨지게 되고


first 변수에는 첫글자만 배열로 반환합니다.


반환된 배열을 Set 으로 담으면 중복이 제거됩니다.


Set을 다시 Array로 변환한 뒤 count를 return 합니다.


이렇게 해서 중복이 제거된 앞글자의 합을 Section count로 return 하였습니다.





2. Section의 title을 생성합니다.


func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int-> String?
cs


return String(Array(Set(self.items.map{ $0.first! })).sorted()[section])
cs


Section count와 동일하게 한글자를 가져오고 각 section에 맞게 title이 셋팅됩니다.






3. 각 Section의 row count를 return 합니다.


public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int-> Int
cs


let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[section]
return self.items.filter{ $0.first! == charactor }.count
cs


현재 Section에 해당되는 첫번째 문자열을 추출합니다.


filter{ $0.first == charactor} 배열에 들어있는 값과 추출한 문자열을 비교하여 맞는 값의 count를 return합니다.






4. 각 row에 data를 대입합니다.


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


let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "CellList"for: indexPath)
cell.textLabel?.text = self.items.filter{ $0.first == charactor }[indexPath.row]
return cell
cs



현재 Section에 해당되는 첫번째 문자열을 추출합니다.


TableViewCell을 연결해줍니다.


filter{ $0.first == charactor } 배열에 들어있는 값과 추출한 문자열을 비교하여 맞는 값을 꺼낸 뒤


그안에서 indexPath.row 에 해당되는 값을 꺼내 textLabel에 넣어줍니다.






이렇게 Section 을 간단하게 분리해 보았습니다.


응용을 한다면 날짜별로 Section을 분리하는것도 쉽게 구현이 가능합니다.


728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

[XCode 11] iOS 13 다크모드 해제  (0) 2019.12.09
Swift 4 UIAlertController  (0) 2019.03.05
Swift 4 UIRefreshControl  (0) 2019.03.04
Swift 4 TableViewCell SwipeAction  (0) 2019.02.21
Swift 4 TextView PlaceHolder  (0) 2019.02.21
728x90
반응형

리스트 형식의 TableView 를 사용할 때에 새로고침 버튼을 두는것보다


아래로 당기면서 새로고침을 진행하는게 좋습니다.


네이버나 페이스북 유튜브의 경우에도 제일 상단 목록을 아래로 당기면 새로운 목록이 나오게 됩니다.


iOS에서도 이러한 기능을 지원을 하고 있어서 정리합니다.





UIRefreshControl 의 내부를 보겠습니다.


@available(iOS 6.0*)
open class UIRefreshControl : UIControl {
 
    
    /* The designated initializer
     * This initializes a UIRefreshControl with a default height and width.
     * Once assigned to a UITableViewController, the frame of the control is managed automatically.
     * When a user has pulled-to-refresh, the UIRefreshControl fires its UIControlEventValueChanged event.
     *
    */
    public init()
 
    
    open var isRefreshing: Bool { get }
 
    
    open var tintColor: UIColor!
 
    open var attributedTitle: NSAttributedString?
 
    
    // May be used to indicate to the refreshControl that an external event has initiated the refresh action
    @available(iOS 6.0*)
    open func beginRefreshing()
 
    // Must be explicitly called when the refreshing has completed
    @available(iOS 6.0*)
    open func endRefreshing()
}
cs


iOS 6.0 버전 이상부터 지원이 가능하고 UIControl 을 상속 받고 있습니다.


isRefreshing 은 현재 리프레쉬가 진행중인지를 나타냅니다.


tintColor 로 색상도 바꿀수 있구요.


attributedTitle 은 새로고침 indicator 아래에 텍스트를 설정합니다.


beginRefreshin 함수는 새로고침 시작을 알립니다.


endRefreshing 함수는 새로고침이 끝남을 알립니다.






이젠 실습으로 구현해 보겠습니다.



Storyboard 의 UIVIewController 에 TableView와 TableViewCell을 만들어 줍니다.


TableViewCell의 Attributes inspactor에 들어가서 indentifier 를 'Cell'로 정의해주었습니다.


Storyboard는 이정도만 만들고 Swift 코드로 넘어가겠습니다.





import UIKit
 
class ViewController: UIViewController {
    
    var array = ["Samsung""Apple""Lg""Google""Facebook"]
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        initRefresh()
    }
    
    // UIRefreshControl 초기 설정
    func initRefresh() {
        let refresh = UIRefreshControl()
        refresh.addTarget(self, action: #selector(updateUI(refresh:)), for: .valueChanged)
        refresh.attributedTitle = NSAttributedString(string: "새로고침")
 
        if #available(iOS 10.0*) {            
            tableView.refreshControl = refresh
        } else {
            tableView.addSubview(refresh)
        }
    }
    
    // 새로고침 함수
    @objc func updateUI(refresh: UIRefreshControl) {
        refresh.endRefreshing() // 리프레쉬 종료
        tableView.reloadData() // 테이블 뷰 로드
    }
}
 
cs


샘플로 만들었으며 array라는 배열에 임이의 값을 넣어주었습니다.


TableView를 IBOutlet 변수로 선언을 해주고 Storyboard의 TableView와 연결을 해주고


delegate와 dataSource를 self로 대입해 나 자신이 delegate와 dataSource 프로토콜을 준수하고 있다고 정의해줍니다.


UIRefrechControl 인스턴스화 하여 target을 설정해주면 스와이프 액션이 주어졌을때 연결한 uidateUI함수를 호출해 줍니다.




iOS 10 이전 버전은 TableView에 view를 등록해 주고, 이후는 TableView에 refreshControl 프로퍼티가 존재함으로 대입해 주면 됩니다. 


updateUI함수가 호출되면 리프레쉬를 종료하는 endRefreshing함수를 호출함으로써 새로고침 UI는 마무리가 되고


TableVIew를 재조회 합니다.





extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
        cell.textLabel?.text = array[indexPath.row]
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int-> Int {
        return array.count
    }
}
cs


TableView 관련코드 입니다.


기존의 글에 많이 동일한 코드를 구현했으니 설명은 생략합니다.







TableView를 아래로 당겨줍니다.






설정했던 '새로고침'과 indicator가 나오면서 테이블을 재조회 합니다.





간단하게 TableView를 Refresh하는 방법을 알아보았습니다.


728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

Swift 4 UIAlertController  (0) 2019.03.05
Swift 4 TableView Section  (0) 2019.03.04
Swift 4 TableViewCell SwipeAction  (0) 2019.02.21
Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
728x90
반응형


Max os 에서 maven을 설치 하는 방법을 작성하려고 합니다.


windows os 환경에서 그냥 되길래 max os 에서도 당연히 되겠다...생각했지만


eclipse 에서 maven 오류가 나서 많은 시간을 소비 했던거 같아요.








그런 분들이 생기지 않게 하려고 이렇게 정리 해서 올립니다.


일단 제 맥은 jdk 1.8.121 버전을 설치 하였고 


maven 버전은 3.9.9로 설치했습니다.(참고해주세요!)







maven을 설치하기 앞서 저장할 디렉토리를 만들어 주었습니다.


터미널에서 cd ~ 로 명령어를 주시면!


기본 home으로 이동을 하실 수 있습니다.


여기서 전 alias를 ll='ls -al' 로 주어서 ll 별칭을 주어 명령어를 실행했습니다.

위와 같은 구조로 보여지게 되는데요.





이와 같은 위치에 maven 이라는 디렉토리를 만들어 주었습니다.

기본 maven 을 설치하기위한 준비는 마쳤습니다.








준비가 끝났으면 본격적인 설치를 진행 해보겠습니다.


http://maven.apache.org.downloan.cgi 를 통해


 bin.tar.gz 다운 받아 만들어둔 maven 디렉토리에 받아줍니다.


maven 디렉토리로 진입 하신다음 "tar -zcvf 파일명.tar.gz" 명령어로 압축을 풀어줍니다.



저는 이렇게 압축이 풀렸는데 버전에 따라 뒤에 숫자가 달라집니다.








vi 편집기를 통해 환경변수를 설정하겠습니다.











i 눌러서 insert를 할수 있게 변경을 합니다.


user 명에 따라서 "/Users/유저명" 유저명 부분은 변경하셔야 합니다.


그리고 전 maven으로 "ln" 명령어를 사용해서 압축 푼 디렉토리를 심볼릭 링크로 연결했습니다.


(예: ln -s apache-maven-3.3.9/)








export 명령으로 환경변수를 지정해 줍니다.


4번째 줄의 내용과 5번째 줄의 내용은 다르지만 실행은 똑같이 됩니다.


maven 홈페이지를 들어가시면 4번째로 설명이 되어있습니다.


나중에 따로 수정할 필요없이 버전 업이 되어도 사용할 수 있도록 4번째 줄을 사용했습니다.


다 입력을 하셨으면 :wq 를 해주셔서 입력과 종료명령을 해줄수 있습니다.








마지막으로 정상적으로 오류없이 입력을 환경변수 설정을 하셨다면


mvn -version 명령을 입력해서 설치여부를 확인할 수 있습니다!




 


정상 설치가 되었다면 이런 출력문이 나오면 끝!!


(~/maven/apache-maven-3.3.9/bin/mvn) 이 들어있어요~!


이로써 Spring framework 를 개발하는데 무리 없이 동작하게 되었습니다!


728x90
반응형
728x90
반응형


회사에서 진행하려는 기획이 있는데


기능으로 간단한 이체도 가능해야 합니다.





정말 많은 PG사가 있고, PAY 업체들도 많지만


이체기능만 필요하기 때문에 엄청난 검색을 시작했습니다.


그렇게 해서 찾게된 '은행권 공동 오픈플랫폼 API'에 대해서 알아 보려고 합니다.




은행권 공동 오픈 플랫폼


https://www.open-platform.or.kr/main


위의 주소를 통해 은행권 공동 오픈플랫폼 홈페이지에 접속할 수 있습니다.







상단 메뉴에서 오픈 API 정보가 있습니다.



서비스 API와 인증/관리 API를 이용할 수 있게 지원하고 있으며


잔액조회, 거래내역조회, 계좌 실명조회, 입금이체, 출금이체의 서비스가 있으며


이를 인증하기 위한 사용자인증, 관리 API가 있습니다.








16개의 참가은행 서비스를 한번에 조회할 수 있으며


참가은행상태조회 API를 통해 거래가능(Y), 장애(D), 개시이전(L), 종료처리(E)로 정의된 코드를 응답하는데


거래가능한 상태일때를 확인하여 입.출금 처리를 할 수도 있습니다.





은행권 공동 오픈플랫폼의 장점은


금융서비스를 편리하게 개발할 수 있도록 참가은행의 서비스를 표준화하여 제공하기 때문에


기업이 금융서비스의 개발에 어렵지 않고


새로운 IT기술을 접목시켜 다양한 핀테크 서비스를 빠르게 출시할 수 있다는점입니다.





금융위원회, 금융감독원, 은행연합회, 금융보안원, 핀테크지원센터에서 협력하고 있기 때문에


안전한 금융서비스를 개발하기 수월 하다고 할 수 있습니다.





많은 보안성심의 부분을 개발단계에서 파악하고 처리할 수있어


문제 될 소지를 미리 제거하는 것이지요.





페이스북, 트위터, 우아한형제들, 쿠팡 등 OAuth 의 표준화된 토큰 기반의 인증방법을 채택해


REST 통신을 할때에도 사용자의 정보를 보호할 수 있습니다.





많은 은행들의 서비스를 쉽고 간편하게 처리할 수 있으면서


보안처리도 확실한 은행권 공동 오픈플랫폼 API 를 사용해서 


질 좋은 서비스를 개발해보는건 어떨까요?





우리에게 편의를 제공하는 API 지원을 해주니 저도 서비스에 사용해보려고 합니다.


다음은 '은행권 공동 오픈플랫폼 API' 신청하는 방법을 알아보겠습니다.




728x90
반응형
728x90
반응형




위와 같이 테이블뷰에 좌측에서 또는 우측에서 스와이프를 하면 나오는 메뉴를 보았을 겁니다.


모바일 기기에 최소한의 정보를 보여주다보니 기능을 숨겨서 사용할 때가 있습니다.


이럴때 사용하기 편한 스와이프 액션을 알아보겠습니다.





override func viewDidload() {
    tableView.delegate = self
}
cs


tableView의 델리게이트를 준수하여 콜백 메소드를 구현했다는 표시로 self를 대입해줍니다.



// Mark: - TableView
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
    ...

    // 셀 우측 스와이프
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        
        let important = importantAction(at: indexPath)
        let delete = deleteAction(at: indexPath)
        return UISwipeActionsConfiguration(actions: [delete, important])
    }
    
    // 셀 좌측 스와이프
    func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let complete = completeAction(at: indexPath)
        return UISwipeActionsConfiguration(actions: [complete])
    }
}
cs


델리게이트를 준수하여 trailing, leading SwipreAction 별칭으로 되어있는 함수를 구현하였습니다.


셀 우측 스와이프를 할때 알람과 삭제 변수를 생성하고 UISwipeActionsConfiguration 함수 호출할때 인자로 넣어줍니다.


배열로 받기 때문에 여러개를 넣어도 되고 한개만 넣어도 됩니다.


셀 좌측 스와이프도 동일합니다.






    // 스와이프 알림
    func importantAction(at indexPath: IndexPath) -> UIContextualAction {
        let todo = todoList[indexPath.row]
        let action = UIContextualAction(style: .normal, title: "알림") { (action, view, success) in
        
            todo.setValue(!((todo.value(forKey: "isTodo"asBool)!), forKey: "isTodo")
            success(true)
        }
        action.image = UIImage(named: "icons8-clock-50")
        action.backgroundColor = UIColor.purple
        return action
    }
    
    // 스와이프 삭제
    func deleteAction(at indexPath: IndexPath) -> UIContextualAction {
        let action = UIContextualAction(style: .destructive, title: "삭제") { (action, view, success) in
            self.todoList.remove(at: indexPath.row)
            self.tableView.deleteRows(at: [indexPath], with: .automatic)
            success(true)
        }
        action.image = UIImage(named: "icons8-trash-can-50")
        action.backgroundColor = .red
        return action
    }
    
    // 스와이프 할일
    func completeAction(at indexPath: IndexPath) -> UIContextualAction {
        let action = UIContextualAction(style: .destructive, title: "할일") { (action, view, success) in
            success(true)
        }
        action.image = UIImage(named: "icons8-checkmark-50")
        action.backgroundColor = .blue
        return action
    }
cs


코드가 길어져 별도의 함수로 정의 하였습니다.


UIContextualAction 인스턴스를 만들어 주었고


이미지를 사용하려고 무료 icon 이미지를 넣어주었습니다.


처리 하고 싶은 로직을 클로저에서 처리하면 됩니다.

 




728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

Swift 4 TableView Section  (0) 2019.03.04
Swift 4 UIRefreshControl  (0) 2019.03.04
Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
Swift 4 WKWebView  (0) 2019.02.20
728x90
반응형

TextField 는 아이디나 비밀번호 입력을 받을때 사용하고

 

TextView는 HTML의 TextArea처럼 긴 글을 입력 받을 때 사용합니다.

 

 

 

 

TextField와 SearchBar는 입력을 한줄로 받기 때문에 PlaceHolder를 설정하여 입력설명을 적을수 있지만.

 

TextView는 별도의 기능을 지원하지 않습니다.

 

 

 

 

그래서 UITextViewDelegate를 준수해서 커스텀을 해야 PlaceHolder 처럼 구현을 할 수 있습니다.

 

Storyboard에서 TextView를 마우스 우클릭해서 컨트롤러에 연결하고 Delegate를 선택해도 되고.

 

override func viewDidLoad() {
    textView.delegate = self
}

 

 

위 처럼 소스 코드로 나 자신이 UITextViewDelegate를 준수하고 있다고 설정해줘도 됩니다.

extension MainViewController: UITextViewDelegate {
    
    // 편집이 시작될때
    func textViewDidBeginEditing(_ textView: UITextView) {
        textViewSetupView()
    }
    
    // 편집이 종료될때
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text == "" {
            textViewSetupView()
        }
    }
    
    // 텍스트가 입력될때
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        // 개행시 최초 응답자 제거
        if text == "\n" {
            textView.resignFirstResponder()
        }
        return true
    }
}
 

 

 

 

 

편집이 시작될 때와 종료 되었을대 textViewSetupView 함수를 호출하도록 하였습니다.

 

현재 텍스트가 '내용입력' 이면 내용을 지우고 입력받을 수 있도록 글씨 색도 검정으로 바꿔주었고,

 

내용이 비어있을때에는 PlaceHolder 처럼 글씨는 회색으로 변경하고 '내용입력'을 넣어주었습니다.

// UITextView PlaceHolder 설정
    func textViewSetupView() {
        if textView.text == "내용입력" {
            textView.text = ""
            textView.textColor = UIColor.black
            
        } else if textView.text == "" {
            textView.text = "내용입력"
            textView.textColor = UIColor.lightGray
        }
    }

 

 

 

 

 

 

텍스트가 바뀔때에는 개행인지 판단하여 응답자를 없애줘서 포커스를 지워줍니다.

 

그러면 키보드도 자동으로 내려갑니다.

 

위와 같이 간단하게 TextView도 PlaceHolder처럼 커스텀해서 사용할 수 있습니다.

 

728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

Swift 4 UIRefreshControl  (0) 2019.03.04
Swift 4 TableViewCell SwipeAction  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
Swift 4 WKWebView  (0) 2019.02.20
Swift 4 TableView 이미지 비동기 처리  (0) 2019.02.20
728x90
반응형

webView.load() 만 실행한다고 해서 WebView 구성이 끝일까요?


사용자는 이 화면이 아직 조회되고 있는지 알아야 합니다.


화면이 오류로 멈춰있는데 언제까지 기다릴수도 없는일 입니다.






iOS에서는 화면의 로딩 중이라는것을 보여주도록 UIActivityIndicatorView를 지원하고 있습니다.





Indicator를 구성하여 웹뷰를 완성해보겠습니다.


    @IBOutlet weak var indicator: UIActivityIndicatorView!
cs


Storyboard에서 Indicator뷰를 생성하고 IBOutlet 변수로 정의합니다.





그리고 WKWebView가 로딩을 시작할 때와, 로딩이 끝날때, 오류일때를 각 함수를 호출해주는 Delegate를 준수하면됩니다.


    webView.navigationDelegate = self
cs


extension MainViewController: WKNavigationDelegate {
 
    // 로드 시작
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: KNavigation!) {
    
    }
 
    // 로드 종료
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
 
    }
 
    // 로드 오류
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        
    }
}
cs


extension이라는 확장 키워드를 통해 WKNavigationDelegate 를 구현하는 함수를 따로 나눠 작성했습니다.


webview의 navigationDelegate를 나 자신으로 정하면 특정 행동을 취했을때 구현한 함수를 호출해줍니다.


WKNavigationDelegate를 준수하면 웹뷰의 많은 콜백 함수들을 사용할 수 있지만 몇가지만 구현해 보았습니다.






Activity Indicator View -> Behavior 


Animating 을 체크하면 indicator가 움직이게 된됩니다.


Hides When Stopped 를 체크하면 indicator가 멈출때 화면에서 감춰줍니다.







indicator.startAnimating()    // indicator가 움직인다.

indicator.stopAnimating()    // indicator가 멈춘다.


필요에 맞게 indicator함수를 호출하면 됩니다.

728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

Swift 4 TableViewCell SwipeAction  (0) 2019.02.21
Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView  (0) 2019.02.20
Swift 4 TableView 이미지 비동기 처리  (0) 2019.02.20
Swift 4 TableView 이미지 메모이제이션 기법  (0) 2019.02.20
728x90
반응형

iOS 8 이상의 앱에서는 UIWebView 사용보단


WKWebView를 사용하라고 문서에 나와있습니다.






장단점이 있겠지만 WKWebView를 사용하는 방법을 정리 하려고 합니다.


기존과 비슷하게 Storyboard의 Library 에서 WebKit View 로 구성하면 됩니다.







    import WebKit
cs


Swift 에서는 위와 같이 import작업이 필요합니다.


Storyboard의 WebKit View를 @IBOutLet 변수로 정의 합니다.



    let url = URL(string: "URL주소")
    let request = URLRequest(url: url)
    webView.load(request)
cs


URL에 원하는 URL주소를 넣고 URLRequest로 변환해준다음


webView.load() 함수를 사용하면 끝입니다.


정말 간단하게 웹뷰를 활용한 앱을 만들수 있습니다.


728x90
반응형
728x90
반응형


테이블 뷰 메모이제이션(memoization) 도 문제점이 있습니다.


데이터가 수십건, 수백건 이라면 화면 로딩이 지연(Blocking) 되는 문제가 생깁니다.






목록을 보여주는 앱이라면 첫 화면부터 대량의 정보를 보여줘야 하기때문에


처음 실행한 부분부터 화면이 보이지 않는다면 오류인줄 알고 앱을 종료해버리고 말것입니다.


거기에 텍스트보다 용량이 높은 이미지를 메모리에 저장까지 해야 하는 부담도 있습니다.






이를 해결하기위해 iOS에서 제공하는 법용 비동기 함수를 이용하는 것입니다.


DispathchQueue.main.async() 라는 비동기 실행 함수를 Swift에서 제공하고 있기 때문에 


내부적으로 스레드에 직접 접근없이 비동기 처리를 할 수 있도록 지원합니다.






이 함수는 블록(Block) 과 GCD(Global Centeral Dispath) 를 이용하여 글로벌 범위에서 사용할 수 있고,


GCD는 애플의 기술로서 병렬처리와 스레드 풀의 기반인 비동기 방식을 구현함으로


멀티코어 프로세서에 적합한 앱을 개발할 수 있도록 지원합니다.







    // 이미지 객체가 존재하면 리턴, 존재하지 않으면 새로 내려받아 저장 후 리턴
    func getImage(_ index: Int-> UIImage {
        
        let model = list[index]
        
        if let imageData = model.imageData {
            return imageData
        } else {
            let url: URL! = URL(string: model.imageUrl!)
            let data = try! Data(contentsOf: url)
            model.imageData = UIImage(data: data)
            return model.imageData!
        }
    }
cs


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
 
    // 비동기 처리    
    DispatchQueue.main.async {
        cell.imgView.image = self.getImage(indexPath.row)
    }
 
    return cell
}
 
cs



이전 메모이제이션 기법과 비동기 처리를 하여 로딩 지연을 방지하도록 수정하였습니다,


이로써 지연에 대한 고민도 해결하고 부드러운 UI를 유지할 수 있습니다.


728x90
반응형

'프로그래밍 > iOS' 카테고리의 다른 글

Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
Swift 4 WKWebView  (0) 2019.02.20
Swift 4 TableView 이미지 메모이제이션 기법  (0) 2019.02.20
Swift 4 TableView 동적 높이 설정  (0) 2019.02.19

+ Recent posts