우리가 위대한 투자자들의 책을 읽는 이유는, 성공을 증명한 이들의 투자방식, 사고, 접근법에 대해 배우기 위해서입니다. 세상 모든 일을 몸소 겪어야 배울 수 있다면 우리는 성공과 실패가 뒤섞인 험난한 삶을 살 수밖에 없습니다.책을 통해 성공과 실패를 배우고 어떻게 해야 할지를 고민해야 합니다.
종자돈 500만원, 1천만원.. 없어도 그만이야..내 방식대로 해볼래.
투자에 대해 공부하지 않아도 어느덧 주식투자 5년차, 10년차로 주식 매매를 할 줄 아는 사람들
생각해 보면, 이런 종자돈, 투자기간은 작아보여도 하찮은게 아니라, 정말 소중한 돈과 시간입니다. 만약 매년 500만원씩 모을 수 있다면, 5년 또는 10년 후에 여러분은 부동산에도 투자할 수 있는 종자돈을 모을 수 있습니다.
최근 전기차, 2차전지, AI에 투자해서 1년에 10배 수익을 낸 엄청난 소수(!!!)의 사람들이 있지만, 우리는 그들이 운이 좋다고 하지 위대하다고 하지는 않습니다. 그리고 주가가 1년에 10배 오르는 과정에서 100%, 300% 먹은 사람들이 많고 500%, 800% 먹더라도 투자금액이 적은 사람들이 대다수라 생각됩니다. 어떤 것이 나에게 맞는 투자방법인지 고민없이, 그들처럼 한달만에 100% 수익을 목표로 또는 매달 10%를 목표로 투자를 하게되면, 매일 주식 가격에 스트레스를 받아 돈을 벌어도 불안하고, 단타로 초반에는 돈을 벌다가 결국엔 손해를 볼 상황이 될 경우가 많습니다.
워런 버핏은 매년 20%씩일지라도전체 금액에 대해 19%씩 수익을 매년 꾸준히 복리로 성장했습니다. 그는 처음에는 주식차트 분석으로 돈을 벌다가 벤자민 그레이엄에게 "가치투자"를 배워 염가 매수 전략을 실행했습니다. 당시 저평가된 주식들이 많아 좋은 투자실적을 나타냈습니다. 그러다 찰리 멍거를 만나
우량하지 않은 기업을 대단히 싸게 매수하는 것보다
싸지 않아도대단히 우량한 기업을 매수하는 것이 훨씬 나은 전략이다.
로 전략을 변경했습니다. 그래서 그는 해자*가 튼튼한 기업(진입 장벽이 높은 기업)에 투자하게 됩니다. * 해자 : 성 주위에 적들이 침범하지 못하게 만든 강, 물줄기
경쟁 우위(브랜드 가치나 특허 등)
높은 시장 점유율 내지 시장 장악력
안전마진(경제 위기를 극복할 수 있는 능력)
가격 전가 능력(가격을 인상해도 매출이 크게 감소하지 않는가)
신뢰성(지속적으로 안정적인 수지 혹은 좋은 수치를 보이는가)
규제 관련 규정을 다뤄본 경험(미디어 기업의 경우)
규모상 우위(대량 매매에 따른 비용 절감 등 규모의 경제에서 오는 우위)
네트워크(아마존, 이베이 등 고객 평가 시스템)
하지만 그는 사실 좋은 주식을 기다렸다가 염가에 사는 경우도 많았습니다. 주식 시장이 호황기 일때는 주식을 매도하고 시장을 관망했지만, 시세가 바닥을 치면 매수자로 돌변해 투자했던 것입니다.
주식을 하다보면, "이거 당장 오를 것 같은데?" 하는 생각으로 예수금을 항상 제로로 만드는 사람들이 많습니다. 하지만 투자를 하기 전에 해당 기업에 대해 많은 검색을 하고, 주가가 오르고 있을지라도 기회를 놓칠지라도 진입하는 가격이 충분히 매력적인지 생각하시기 바랍니다.
들어가서 10% 먹고 나가겠다는 트레이더의 생각이라면 모르지만, 매일, 매시간 주가 변동을 신경쓸 수 없다면, 긴 안목으로 여유를 가지고 투자해야 주가 변경에도 스트레스 없이 좋은 결과를 보실 수 있습니다.
1. 코인으로 인한 인생 역전한 사람 탄생 2. 아파트 가격 2배 상승으로 인한 많은 사람들의 자산 증식 3. 코로나19시절에 많은 자영업자들의 추락과 함께 이커머스의 상승 4. 테슬라(전기차)로 시작되었지만, 23년부터 시작된 2차전지 테마주 폭등
그 이전에 아등바당 노력했던 것들이 무슨 의미가 있었나 싶을 정도로 노동의 가치와 지루했던 투자는 사라지고, 한방에 한순간의 도전으로 인생 역전하는 사람들이 뉴스에 나오면서, 가만히 있으면 뒤쳐지는 것 같아 불안하고 초조해하는 사람들이 많습니다. 그러다 증권사에서 추천종목 기사를 보면서 투자했다가 물려, 정말 좋은 투자기회를 놓치기도 합니다.
한방, 한순간으로 인한 인생 역전자는 많지 않습니다.
워렌버핏의 책을 읽고, 그가 운영하는 버크셔 해서웨이가 대단한 것은 2차전지를 통해 1년만에 1000%수익을 내는 것이 아니라, 매년 15~25%씩 꾸준히 수익을 내는 것입니다. (복리의 효과) 우리는 2차전지에 투자해서 10배 먹는 것을 기대하는 것이 아니라, 좋은 기업을 찾아 안정적으로 투자자산을 늘리는 것을 목표로 해야 재정적, 정신적으로 안정적인 삶을 살 수 있습니다.
1년 늦게 투자한다고 해서 좋은 기회를 놓칠 수도 있겠지만, 항상 기회는 새로운 모습으로 계속 우리에게 오고 있습니다. 오히려 섣부른 판단으로 좋은 투자처를 찾아도 자금이 없어 기회를 활용 못할 수 있으니 조바심을 내지 않아야 합니다.
* 2차전지를 통해 2배, 3배 먹은 사람들 많이 있을 것입니다. 하지만 그들 대다수의 투자금액은 많지 않을 것이고, 투자금액이 많은 사람들 중 수익률이 300%를 넘는 사람들은 드물 것입니다.
좋은 기업을 찾아야 합니다.
필립 피셔는 좋은 기업을 찾기 위해서는 재무재표는 기본적으로 보고, 미래 성장성도 확인하고, 무엇보다 경영진의 자질이 중요하다고 합니다. 그는 어떤 주식을 살 것인가를 투자 대상 기업을 찾는 15가지 포인트로 정리하였습니다.
1. 적어도 향후 몇 년간 매출액이 상당히 늘어날 수 있는 충분한 시장 잠재력을 가진 제품이나 서비스를 갖고 있는가? 2. 최고 경영진은 현재의 매력적인 성장 잠재력을 가진 제품 생산라인이 더 이상 확대되기 어려워졌을 때에도 회사의 전체 매출액을 추가로 늘릴 수 있는 신제품이나 신기술을 개발하고자 하는 결의를 갖고 있는가? 3. 기업의 연구개발 노력은 회사 규모를 감안할 때 얼마나 생산적인가? 4. 평균 수준 이상의 영업 조직을 가지고 있는가? 5. 영업이익률을 충분히 거두고 있는가? 6. 영업이익률 개선을 위해 무엇을 하고 있는가? 7. 돋보이는 노사 관계를 갖고 있는가? 8. 임원들간에 훌륭한 관계가 유지되고 있는가? 9. 두터운 기업 경영진을 갖고 있는가? 10. 원가 분석과 회계 관리 능력은 얼마나 우수한가? 11. 해당 업종에서 아주 특별한 의미를 지니는 별도의 사업 부문을 갖고 있으며, 이는 경쟁업체에 비해 얼마나 뛰어난 기업인가를 알려주는 중요한 단서를 제공하는가? 12. 이익을 바라보는 시각이 단기적인가 아니면 장기적인가? 13. 성장에 필요한 자금조달을 위해 가까운 장래에 증자를 할 계획이 있으며, 이로 인해 현재의 주주가 누리는 이익이 상당 부분 희석될 가능성은 없는가? 14. 경영진은 모든 것이 순조로울 때는 투자자들과 자유롭게 대화하지만 문제가 발생하거나 실망스러운 일이 벌어졌을 때는 "입을 꾹 다물어버리지" 않는가? 의문의 여지가 없을 정도로 진실한 최고 경여진을 갖고 있는가?
최근 기사를 보면 에이블씨엔씨에서 한샘으로 이직한 김유진대표가 예상했던 인력구조조정이 아니라 내부 효율화를 통해 흑자전환에 성공한 사례, 바이오업계들이 내부 영업부를 축소하고 영업을 외부 전문업체에 맡기면서 발생하는 외주비가 최근 급격히 증가하여 이익금이 줄어들고 있다는 상황, 경영진의 비리로 문제되고 있는 카카오 전체, 철강 사업 원조 포스코의 해외 자원 사업 진출 성공 등 경영진의 자질에 회사의 가치가 달라진 사례를 확인할 수 있습니다.
지나친 분산투자로 제대로된 분석없이 증권사의 추천기사로 수많은 종목에 분석없이 들어가기 보다는 분야를 정하고, 서로 다른 섹터(업종)에서 투자종목에 대해 분석한 후, 가격이 충분히 매력적이라고 판단될 때 매수해야 건강한 투자생활을 할 수 있습니다.
viewController화면을 클릭한 후, navigation Controller 버튼을 클릭
나. library 팔레트에서 "View Controller"를 끌어다가 메인화면 컨트롤러의 오른쪽 빈 공간에 놓습니다.
View 추가
다. library 팔레트에서 "Bar Button Item"을 찾아 네비게이션 바의 오른쪽에 끌어다 놓습니다. 그리고 Arributes inspector의 system item 에 값을 Edit 등으로 변경합니다.
라. EDIT 버튼을 마우스 오른쪽 버튼으로 클릭한 채 오른쪽의 뷰 컨트롤러에 갖다 놓습니다. 그러면 검은색 창에 Action Segue를 Show로 선택합니다. 그러면 "메인화면"에서 서브화면으로 갔다가 돌아오는 형태를 취하게 됩니다. 그러면 별도의 코딩이 없어도 화면 전환이 가능합니다.
마. 새로운 화면은 뷰 컨트롤러 클래스 파일이 없어, 메뉴에서 File-New-File.. 에서 Cocoa Touch Class를 선택합니다. SubClass는 UIViewController로 하고 클래스명은 ***ViewController로 저장합니다.
view controller 파일 생성
바. Main.storyboard 파일에서 새로 추가한 뷰 컨트롤러(화면)을 선택한후, Identity inspector를 클릭한 후, Class에 새로 만든 ***ViewController 를 선택하여 연결시킵니다.
자. didMessageEditDone함수에서 메시지 전달 : txMessage.text = message
차. EditViewController에서 delegate 변수 생성 : var delegate : EditDelegate?
카. 수정화면의 btnDone()함수 를 통해 메인화면으로 값 전달하는 부분 생성 : delegate?.didMessageEditDone(self, message : txMessage.text!)
타. 메인스토리의 ViewController에서 prepare()문에 한줄 추가 : editViewController.delegate = self
//// ViewController.swift// Navigation//// Created by abdurl on 2023/09/20.//import UIKit
classViewController: UIViewController, EditDelegate{
let imgOn =UIImage(named: "lamp_on.png")
let imgOff =UIImage(named: "lamp_off.png")
var isOn =true@IBOutletvar txMessage: UITextField!
@IBOutletvar imgView: UIImageView!
overridefuncviewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imgView.image = imgOn
}
overridefuncprepare(forsegue: UIStoryboardSegue, sender : Any?) {
let editViewController = segue.destination as!EditViewControllerif segue.identifier =="editButton" {
//버튼을 클릭한 경우
editViewController.textWayValue ="segue : use button"
} elseif segue.identifier =="editBarButton" {
//바 버튼을 클릭한 경우
editViewController.textWayValue ="segue : use Bar button"
}
editViewController.isOn = isOn
editViewController.textMessage = txMessage.text!
editViewController.delegate =self
}
funcdidMessageEditDone(_controller: EditViewController, message: String ) {
txMessage.text = message
}
funcdidImageOnOffDone(_controller: EditViewController, isOn: Bool) {
self.isOn = isOn
if isOn {
imgView.image = imgOn
} else {
imgView.image = imgOff
}
}
}
import UIKit
protocolEditDelegate{
funcdidMessageEditDone(_controller : EditViewController, message : String )funcdidImageOnOffDone(_controller : EditViewController, isOn : Bool)
}
classEditViewController: UIViewController{
var textWayValue : String=""var textMessage : String=""var delegate : EditDelegate?
var isOn =true@IBOutletvar txMessage: UITextField!
@IBOutletvar lblWay: UILabel!
@IBOutletvar swIsOn: UISwitch!
overridefuncviewDidLoad() {
super.viewDidLoad()
lblWay.text = textWayValue
txMessage.text = textMessage
swIsOn.isOn = isOn
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/@IBActionfuncbtnDone(_sender: UIButton) {
if delegate !=nil {
delegate?.didMessageEditDone(self, message: txMessage.text!)
delegate?.didImageOnOffDone(self, isOn: isOn)
}
//navigationController?.popViewController(animated: true)_= navigationController?.popViewController(animated: true)
}
@IBActionfuncswImageOnOff(_sender: UISwitch) {
if sender.isOn {
isOn =true
} else {
isOn =false
}
}
}
# 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기
가. 아이폰 모양의 스토리보드의 상단을 드래그 한 후, "delete" 버튼으로 화면에 내용 삭제 : 빈 화면 만들기
나. 프로젝트 내의 ViewControllers.swift파일 삭제
다. Library 팔레트에서 Table View Controller를 선택해서 스토리보드에 올려 놓습니다.
item을 삭제처리하는 부분을 추가하고, 문구를 변경(delete -> 삭제) 로 변경하면 끝.. 그외는 모든 것은 기본 제공.
// Override to support editing the table view.overridefunctableView(_tableView: UITableView, commiteditingStyle: UITableViewCell.EditingStyle, forRowAtindexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
items.remove(at: (indexPath asNSIndexPath).row)
itemsImageFile.remove(at: (indexPath asNSIndexPath).row)
tableView.deleteRows(at: [indexPath], with: .fade)
} elseif editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
// 문구를 Delete에서 "삭제" 로 변경하는 방법overridefunctableView(_tableView: UITableView, titleForDeleteConfirmationButtonForRowAtindexPath: IndexPath) -> String? {
return"삭제"
}
******* 목록 삭제하기2 *******
overridefuncviewDidLoad() {
super.viewDidLoad()
// 아래 코드는 주석처리 되어 있었기에, 주석해제만 하면 됨... 즉 // 만 삭제하면 됨self.navigationItem.rightBarButtonItem =self.editButtonItem
// 아래와 같이 왼쪽에 Edit 버튼을 배치할 수도 있습니다.//self.navigationItem.leftBarButtonItem = self.editButtonItem
}
***** 목록 편집하기 (목록 순서바꾸기) *****
아래의 함수는 원래 주석되어 제공되는데, 주석을 풀고 실행을 하면... "Edit" 편집버튼을 누르면, 오른쪽에 3줄짜리 버거 버튼이 항목마다 오른쪽에 생긴다. 그리고 순서를 저장해야 한다면, 아래와 같이 코드를 추가해야 한다.
뷰가 처음 보일때 호출 되는 함수의 순서는 ViewDidLoad -> ViewWillAppear -> ViewDidAppear 순입니다. 하지만, 뷰가 전환되어 나타날 때는 ViewWillAppear -> ViewDidAppear 만 호출됩니다. ! 이것으로 최초 화면 로딩시에만 호출할 내용은 ViewDidLoad에 넣으면 됩니다.
* 삼원색인 RGB(red green blue)와 투명도 Alpha 값을 사용하는 방법은 아래의 UIColor클래스을 이용하는 것으로, rgb는 0~1사이의 실수값으로 사용되는 색상은 0~255사이의 값으로 표현됩니다. 투명도(alpha)는 0~1사이의 실수값을 가집니다.(0:투명, 1:불투명)
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)// example let red =UIColor(red:1, green:0, blue:0, alpha:1)
let myColor =UIColor(red:1, green : 165/255, blue:0, alpah:1)
# 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기
가. 탭바 컨트롤러 추가 : 스토리보드(Main.swift)의 아이폰 화면 전체를 드래그한 후 메뉴에서 "Editor-Embed in-Tab Bar Controller"를 선택합니다.
아이폰 화면을 전체 선택한 후, Editor-Embed in-Tab Bar Controller 선택
나. 다른 프로젝트 등에 있던 ViewController.swift파일을 복사해서 이름을 MapViewController.swift등 변경 후, 현재 프로젝트내 ViewController 파일과 동일한 위치에 배치합니다. (파일명을 바꾸면서, 파일안에 클래스명도 MapViewController로 동일하게 변경)
다. 다른 프로젝트의 스토리보드의 화면을 전체 선택해서 복사한 이후, 현재 프로젝트의 스토리보드 상의 빈곳을 클릭한 후 붙여넣기(command+V)를 합니다. 이따, Identity inspector를 클릭해서 Class를 ViewController가 아닌 MapViewController로 변경합니다.
라. "Tab Bar Controller" 라고 적힌 뷰 컨트롤러를 마우스 오른쪽 버튼을 클릭한 후, 다.에서 복사한 뷰 화면 안의 빈공간에 드래그합니다. 그러면 연결선이 나타나며 뷰 컨트롤러가 전체적으로 파랗게 됩니다. 이 때 손을 놓으면 됩니다.
탭 바에서 새로운 ViewController 연결연결은 view controllers로 설정
스토리보드(화면) 당 viewController.swift 한개로 1:1 매칭임을 기억하고, 화면 전환은 tabBarController?.selectedIndex = 1 이런식으로 변경할 수 있다. 또한 다른 프로젝트의 화면과 viewController를 그대로(이름만 변경해서) 가져오기 때문에 재활용성이 높습니다.
classViewController: UIViewController{
overridefuncviewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBActionfuncbtnMoveImageView(_sender: UIButton) {
tabBarController?.selectedIndex =1
}
@IBActionfuncbtnMoveDatePickerView(_sender: UIButton) {
tabBarController?.selectedIndex =2
}
}
요약 - 페이지컨트롤러를 이용할 수 있습니다. - 탭바를 이용하면기존 화면을 최대한 재활용할 수 있습니다. 화면 1개당 1개의 viewController.swift가 필요합니다.
url을 String으로 받아 URLRequest로 받은 후, Web View 객체에 로드하면 됩니다. 만약 시뮬레이터에서 작동하지 않는다면, 프로젝트에서 Info.plist 파일을 열어 인터넷 관련 권한을 추가 설명해야 합니다. App Transport Security Settings에 + 를 누르고, Allow Arbitrary Loads를 선택하고 Value를 No 에서 Yes로 변경합니다. 그리고 시뮬레이터를 재시작합니다.
funcloadWebPage(_url:String) {
let myUrl =URL(string: url)
let myRequest =URLRequest(url : myUrl!)
myWebView.load(myrequest)
}
나. 액티비티 인디케이터로 로딩보이기
로딩을 기다릴 때, 화면 가운데서 돌아가는 원 모양의 점선이 바로 '액티비티 인디케이터 뷰'입니다. library 팔레트에서 Activity Indicator View를 선택한 후, WebKit View 위에 올려둔 후, Hide When Stopped로 동작을 멈추면 보이지 않게 설정합니다. 그 이후 코딩으로 webView를 설정하여 애니메이션을 작동.중지시키고, 숨기는 등의 행동의 재정의합니다.
Refresh, Stop, Forward, Backward 등의 아이콘은 속성창의 System Item에서 제공하고 있어 이용하면 됩니다.
제공하는 아이콘(Refresh)를 이용하는 모습
다. 앱 로딩시, 웹페이지 나타나도록 하기(로딩)
"Info.plist"파일을 수정해야 함. 목록에서[App Transport Security Settings]을 선택한 후, "+" 를 클릭하여,[Allow Arbitrary Load]을 선택하고, 오른쪽 Value의 값을 "NO"에서"YES"로 변경하면, 실행시 지정한 웹페이지가 보임.
- 맵뷰로 별도로 세그먼트 컨트롤이 있는데, 기능상 버튼과 동일한데 실제 어떤 것이 선택되었는지 알 수 있어 편리함
세그먼트 컨트롤(segment control) 화면
맵뷰를 실행했는데 아래와 같은 오류가 발생했다면, 프로젝트의 Info.plist파일을 열어 Information Property List 위로 가져가 + 클릭하여 "Privacy-Location When In Use Usage Description"을 선택하고 value를 더블클릭하여 "App needs location servers for stuff"로 수정하면 됩니다.
This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an “NSLocationWhenInUseUsageDescription” key with a string value explaining to the user how the app uses this data
[VKDefault] MissingMeshRenderablesfor ground mesh layer for (4/4) of ground tiles. Tile debug info: (Key: 55.24.6.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 1, PendingMaterial count: 1, InvisibleMeshInstances count: 0| Key: 54.25.6.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 1, PendingMaterial count: 1, InvisibleMeshInstances count: 0| Key: 55.25.6.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 1, PendingMaterial count: 1, InvisibleMeshInstances count: 0| Key: 54.24.6.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 1, PendingMaterial count: 1, InvisibleMeshInstances count: 0)
[Font] Failed to parse font key token: hiraginosans-w6
[Font] Failed to parse font key token: hiraginosans-w6
요약 - WebView로 기본기능이 있는 브라우저를 만들수 있다. Info.plist파일에서 권한 설정을 하고, 아이콘들은 모두 설정에서 필요에 맞는 것을 찾아 바꿔준다. - MapView는 지도 권한을 Info.plist파일에 부여하고, 즐겨찾기/특정지역도착시 알림음 등을 개발할 수 있다.
피커 뷰가 상호작용하려면 피커 뷰에 대한 델리게이트 메소드를 사용해야 합니다. 특정 객체와 상호 작용할 때 메시지를 넘기면 그 메시지에 대한 책임은 델리게이트로 위임됩니다. 즉, 사용자가 객체를 터치했을 때 해야할 일을 델리게이트 메소드에 구현하고 해당 객체가 터치되었을 때 델리게리트가 호출되어 위임 받은 일을 하게 되는 것입니다.
가. 피커 뷰의 델리게이트 사용을 설정하기 위하여 마우스 오른쪽 버튼으로 피커 뷰를 선택한 후, 위쪽의 뷰 컨트롤러 아이콘 위로 끌어다 놓습니다. 그리고 선택화면이 나오면 'delegate'를 선택합니다.
요약 : - 피커 뷰는 delegate를 설정한 후, pickerView라고 타이핑하면 나오는 함수들 중에서 필요한 것을 재정의하면 됩니다. - Alert창은 alert, action을 정의해서 합친 이후 필요시 action에 따른 동작(이벤트)을 handler에 연결시켜주면 됩니다.
이미지를 선언하고, 변수에 할당하는 것은 다른 언어와 비슷합니다. 다만, 이미지 사이즈를 변경할 때 변수타입이 CGFloat타입임을 알아야 하며, 크기조절할 때 ImageView객체.frame.size의 값을 CGSize(width:,height:)로 재설정한다는 것을 기억하면 됩니다.
라이브러리에서 데이트피커(Date Picker)를 선택해서 메인스토리보드에 배치하고, Attributes inspector 를 클릭한 후, Style을 wheel로 변경하고, mode를 원하는 값을 설정합니다. 기본 설정값은 Date and Time입니다. 표기를 한글로 바꾸려면 Attributes inspector 에서 Locale 값을 Korean 으로 변경합니다.
// fomatter를 이용해서 날짜와 시간을 표시하는 방법@IBActionfuncchangeDatePicker(_sender: UIDatePicker) {
let datePickerView = sender
let formatter =DateFormatter()
formatter.dateFormat ="yyyy-MM-dd HH:mm EEEE"
lblPickerTime.text ="선택시간 : "+ formatter.string(from:datePickerView.date)
}
필드
심벌
결과
의미
년도(Year)
yy
23
두 자리로 연도 표시
yyyy
2023
네 자리로 연도 표시
월(Month)
M
9
한글자로 월 표시
MM
09
두 자리로 월 표시
MMM
Sep
영문 3자리로 월 표시
MMMM
September
영문 풀단어로 월 표시
주(Week)
w
6
1~52까지 연간 주 순서(week of year) 표시
ww
06
01~52까지 2자리로 연간 주 순서(week of year) 표시
W
4
1~6까지 월간 주 순서(week of month) 표시
일(Day)
d
8
1~31 까지 일을 표시
dd
08
01~32 까지 2자리로 일을 표시
D
35
1~366까지 연간 일 순서(day of year)를 표시
DD
35
01~366까지 연간 일 순서(day of year)를 표시
DDD
035
001~366까지 연간 일 순서(day of year)를 표시
요일(weekday)
E,EE,EEE
Mon
Sunday~Saturday까지 3글자로 요일 표시
EEEE
Monday
Sunday~Saturday까지 요일 전체 이름 표시
EEEEE
M
한 글자 약어 요일 표시
e
4
1~7까지 주간 날짜 순서 표시
ee
04
01~07까지 주간 날짜 순서 표시
시기(period)
a
PM
AM/PM 표시
시간(Hour)
h
3
1~12까지 시각을 표시
hh
03
01~12까지 시각을 표시
H
15
1~24까지 24시간 시각을 표시
HH
15
01~24까지 24시간 시각을 표시
분(minute)
m
36
0~59까지 분을 표시
mm
36
00~59까지 두자리로 분을 표시
초(second)
s
44
0~59까지 초를 표시
ss
44
00~59까지 두자리로 초를 표시
지역(Zone)
z
GMT+09:00
타임존 표시
Z
+0900
GMT 시간차 표시
// Timer.scheduledTimer을 이용해서 1초 단위로 화면의 시간을 갱신
class ViewController: UIViewController {
let timeSelector:Selector = #selector(ViewController.updateTime)let interval = 1.0
var count = 0
@IBOutlet var lblCurrentTime: UILabel!
@IBOutlet var lblPickerTime: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
Timer.scheduledTimer(timeInterval: interval, target: self, selector:timeSelector, userInfo: nil, repeats: true)
}
@objc func updateTime() {
let date = NSDate()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss EEEE"
lblCurrentTime.text = "현재시각 : " + formatter.string(from: date as Date)
}
}
요약 - DatePicker에 Timer.scheduledTimer()를 이용해서 현재 시간을 1초단위로 갱신할 수 있고, 특정시간에 이벤트를 발생시킬수 있다.