iOS 9강 현상금 랭킹앱 복습

린다·2021년 1월 27일
0

iOS beginner

목록 보기
10/14
post-thumbnail

프로토콜 실습

  1. 테이블 뷰 넣고 auto layout
  2. 테이블 뷰 셀 넣음
  3. 프로토콜 작성
  4. 그 중에 reusable cell identifier랑 table view cell 연결

커스텀 셀

  1. class 따로 작성
class ListCell: UITableViewCell{
}
  1. 그 안에 들어갈 컴포넌트 작성
class ListCell: UITableViewCell{
	@IBOutlet weak var imgView: UIImageView!
	@IBOutlet weak var nameLabel: UILabel!
	@IBOutlet weak var boutyLabel: UILabel!
}
  1. 스토리보드로 가서 table view cell의 custom class에 ListCell 넣어줌 (cell과 커스텀 셀 클래스 연결시켜주는거임!!!)

  2. cell UI변경
    → cell 높이 변경
    → Table View에서 cell 높이 정할 수 있음 (automatic 해제)
    → 컴포넌트 추가(image view, uilabel 2개) + 오토레이아웃 설정
    → UIComponent 코드랑 연결하기 (동그라미 채우기)

  3. 필요한 데이터 넣기 (이름, 현상금 정보 리스트로) → 프로토콜 셀 갯수 리턴: return bountyList.count로 변경

  4. 이미지 asset에 넣기

  5. tableView 어떻게 보여줄까(cellForRowAt) : cell이 지금 UITableViewCell인데 우리가 쓰고 싶은건 ListCell이기 때문에 캐스팅 해줘야함 + optional이 될 수도 있기때문에 고려해줘야함

guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else{
	return UITableViewCell()
}
return cell
//똑같은 내용 if let 문으로도 작성이 가능함
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell {
	return cell
} else {
	return UITableViewCell()
}
  1. cell 안에 들어갈 데이터 세팅해줘야함 코드로
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell {
	let img = UIImage(named: "\(nameList[indexPath.row])") //각 셀 순서에 맞는 이미지 가져옴
	cell.imgView.image = img //이미지 세팅
	cell.nameLabel.text = nameList[indexPath.row]
	cell.bountyLabel.text = "\(bountyList[indexPath.row])" //text는 string 타입인데 bountyList element들은 int type이라서 "" string 타입 처리 해줘야함
	return cell
} else {
	return UITableViewCell()
}

여기까지 하면 각 셀에 맞는 데이터까지 뜨는거까지 완료


뷰컨트롤러 모달로 띄우기

  1. DetailViewController 파일 생성 및 스토리보드에서 view 추가함
  2. 새로 추가한 뷰에 class를 detailViewController로 세팅해줌 (컨트롤러 연결)
  3. 닫는 버튼 컴포넌트 추가 및 이미지 설정 + 오토레이아웃 설정
  4. 닫히는 액션 추가하기 위해 컨트롤+버튼 → 코드로 끌고와서 action 추가(method name: close) → view controller 안에 넣어줘야함
  5. 닫히는 액션: dismiss
dismiss(animated: true, completion: nil) //completion: 화면이 닫히고 나서 되어야할 일
  1. 컨트롤러와 컨트롤러 연결하려면 한 컨트롤러에서 컨트롤 누르고 다른 뷰에 연결 → 타입을 어떻게 연결할거냐: present modally (화면이 아래에서 위로 올라오는...)

  2. 두 개 사이에는 여러 세그웨이로 연결될 수 있음 → id를 설정하면 특정 세그웨이를 활성화시킬 수 있음 → 연결된 줄 선택하고 sague 아이디 설정해주기 (showDetail)

  3. 셀이 눌렸을 때 화면이 떠야하기 때문에 프로토콜 중에 tableView didSelectRowAt(터치하면 어떻게 할거야?)에 가서 코드 추가

performSegue (withIdentifier:"showDetail" , sender: nil)
//세그웨이를 구분하는 구분자는 스토리보드에서 아이디로 주었던 showDetail쓰고
//sender는 세그웨이 실행시킬 때 같이 보낼 수 있는 것, 아직은 nil로 설정

여기까지 하면 모달이랑 연결은 되는데 아직까지 아무것도 안뜨는 페이지 보임

  • cell 누르고 그 설정에서 보면 selection을 변경할 수 있음. 눌리면 어떤 색으로 보일건지 고를 수 있음~

뷰 컨트롤러간 데이터 넘기기

  1. 스토리보드에서 모달 화면 꾸미기, 컴포넌트 추가 + 오토레이아웃 추가
  2. 바운티뷰컨트롤러에서 ListCell 속성들 복사해서 디테일뷰컨트롤러에 붙여넣기
  3. 컴포넌트랑 코드 아웃렛 연결하기~ (동그라미 채우기)
  4. 이름잇으면 이미지를 얻어낼 수 있기 때문에 디테일뷰에 이름이랑 현상금정보만 변수 만들어줌
var name: String?
var bounty: Int?
  1. 추가적으로 디테일뷰에 name, bounty가 꽂혀있으면 uicomponent에 해당 데이터를 넣을 수 있음 → 그걸 꽂아주는 updateUI 코드 작성하기
  • viewDidLoad는 뷰가 보이기 바로 직전에 호출되는 함수 → 여기서 updateUI() 시켜주면 됨
func updateUI(){ 
	//setting은 정보가 있을때 하면 됨, optional binding 사용
	if let name = self.name, let bounty = self.bounty{
		let img = UIImage(named: "\(name).jpg")
		imgView.image = img
		nameLabel.text = name
		bountyLabel.text = "\(bounty)"
	}
}
  1. detailviewcontroller에서 data가 있는 경우 세팅하는 코드는 다 작성했기 때문에 이제 bountyviewcontroller에서 name, bounty를 전달하는 코드만 잘 작성하면 됨
  • 어떻게 줄거냐~ : 우리가 셀 클릭하면 performSegue가 호출됨 근데 또 세그웨이가 호출돼서 실행되기 직전에 세그웨이를 준비하는 method가 있음
//원래 UIViewController에 있는 함순데 우리가 지금 쓰는 뷰컨트롤러는 그걸 상속받은 BountyViewController이고 우리가 다시 쓰려고 하기 때문에 override 해줘야함
//세그웨이를 준비할 때, 직전에 데이터를 넘겨주자! 를 코드로 쓰면 됨
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
	//DetailViewController한테 데이터를 줄거예요~ㅋㅋ -> 힌트를 performsegue sender에 넣어서줌
}
performSegue (withIdentifier:"showDetail" , sender: indexPath.row)
//세그웨이가 실행될때 힌트를 indexPath.row 우리가 몇 번째 셀을 눌렀는지 전달해줌
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
	//실행되는 세그웨이의 아이디가 showDetail일때~
	if segue.identifier == "showDetail" {
		let vc = segue.destination as? DetailViewController //세그웨이의 목적지: DetailViewController
		//segue.destination을 통해서 서브 뷰 컨트롤러의 인스턴스를 참조할 수 있다. 서브 뷰 컨트롤러는 외부로부터 전달받을 데이터에 대한 프로퍼티를 만들어두고, 메인 뷰 컨트롤러가 이 메소드 내에서 데이터를 할당해주면 된다.
		//서브 뷰 컨트롤러가 초기화된 시점에서는 해당 프로퍼티 값을 가지고 있지 못하기 때문에 서브 뷰 컨트롤러에서는 외부에서 넣어줘야 하는 값에 대해서 옵셔널로 선언해야함.
		if let index = sender as? Int {
			vc?.name = nameList[index]
			vc?.bounty = bountyList[index]
		}
		//이 두 개의 정보를 꽂아주고 싶은 거임.
	}
}

0개의 댓글

관련 채용 정보