Skip to content

Conversation

@JinUng41
Copy link
Collaborator

👻 PULL REQUEST

📄 작업 내용

  • 와블 컴포넌트 구현하였습니다.
    • 액션 시트 (추후 수정 요망)
    • 404 페이지
    • 로딩뷰 페이지
    • 사진 상세 페이지
    • CTA 버튼
구현 내용 IPhone 13 mini
WableButton(CTA)
404페이지
로딩뷰페이지
사진상세페이지
액션 시트

💻 주요 코드 설명

WableButton (CTA)

  • UIButton.Configuration.filled()를 사용하였습니다.
  • 4가지의 스타일을 정의하였습니다. (primary, pale, gray, black)
  • init(style:)을 이용하여 WableButton을 생성할 수 있습니다.
WableButton.swift
final class WableButton: UIButton {
    
    // MARK: - WableButton Style

    enum Style {
        case primary
        case pale
        case gray
        case black
    }
    
    // MARK: - Property

    private var style: WableButton.Style {
        didSet {
            setupButton()
        }
    }
    
    // MARK: - Initializer

    init(style: WableButton.Style) {
        self.style = style
        
        super.init(frame: .zero)
        
        setupButton()
    }

    // ...생략
}

// 사용 예시
private let backToHomeButton = WableButton(style: .black).then {
    var config = $0.configuration
    config?.attributedTitle = "홈으로 가기".pretendardString(with: .body1)
    $0.configuration = config
}

🔗 연결된 이슈

@JinUng41 JinUng41 added ✨ feat 기능 또는 객체 구현 🍻 진웅 술 한잔 가온나~ labels Mar 14, 2025
@JinUng41 JinUng41 added this to the 리팩토링 마감 milestone Mar 14, 2025
@JinUng41 JinUng41 requested a review from youz2me March 14, 2025 01:56
@JinUng41 JinUng41 self-assigned this Mar 14, 2025
Copy link
Member

@youz2me youz2me left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다! 언제 봐도 코드가 정말 깔끔하네요 😮
궁금띠예인 부분을 리뷰에 적어놓았어요. 답변해주시면 감사하겠습니다!


private let loadingDuration: TimeInterval = 1.6

// MARK: - Initializer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init()도 LifeCycle에 포함되는데 따로 분리하신 이유가 궁금해요 !!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

물론 이니셜라이저도 라이프 사이클에 포함되나, 의존성 주입이나 객체 구성 방식을 결정하며 이니셜라이저는 외부에서 명시적으로 호출됩니다.
그렇기 때문에 라이프 사이클의 다른 메서드와는 특징이 다르다고 생각하는데요.
그러한 이유로 저는 별도의 마크 주석으로 작성하고 있습니다.

Comment on lines +63 to +70
private func startAnimationAndDismiss() {
loadingAnimationView.play()

DispatchQueue.main.asyncAfter(deadline: .now() + loadingDuration) {
self.loadingAnimationView.pause()
self.dismiss(animated: true)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 ... 다른 뷰컨에서도 쓸 수 있을 것 같은데 익스텐션으로 분리해보는 것도 좋을 것 같아요!

Comment on lines +22 to +26
private let dismissButton = UIButton().then {
var configuration = UIButton.Configuration.plain()
configuration.image = .btnRemovePhoto
$0.configuration = configuration
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lazy var로 선언 안하신 이유가 궁금해요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재의 화면에서는 반드시 필요한 버튼이며, 뷰컨트롤러 인스턴스에 의존하지 않기 때문에 lazy var보다는 let으로 선언하였습니다.

Comment on lines +88 to +92
let dismissAction = UIAction { [weak self] _ in
self?.dismiss(animated: true)
}

dismissButton.addAction(dismissAction, for: .touchUpInside)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 ... addAction을 생각 못했네요. 굿굿 !!!

Comment on lines +98 to +107
private extension PhotoDetailViewController {
var optimalImageViewHeight: CGFloat {
let aspectRatio = image.size.height / image.size.width
let screenWidth = UIScreen.main.bounds.width
let height = screenWidth * aspectRatio

let maxHeight: CGFloat = 812.adjustedHeight

return min(height, maxHeight)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +13 to +40
typealias CompletionHandler = (_ completion: @escaping (Bool) -> Void) -> Void

// MARK: - WableActionSheetConfiguration

struct WableActionSheetConfiguration {
let title: String
let message: String?
let confirmButtonTitle: String
let cancelButtonTitle: String?
let confirmAction: CompletionHandler?
let cancelAction: CompletionHandler?

init(
title: String,
message: String? = nil,
confirmButtonTitle: String,
cancelButtonTitle: String? = nil,
confirmAction: CompletionHandler? = nil,
cancelAction: CompletionHandler? = nil
) {
self.title = title
self.message = message
self.confirmButtonTitle = confirmButtonTitle
self.cancelButtonTitle = cancelButtonTitle
self.confirmAction = confirmAction
self.cancelAction = cancelAction
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

복잡해지기 쉬운 코드인데 이렇게 하니까 코드가 엄청 깔끔해졌네요 👀

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하지만 더 좋은 코드로 찾아뵙겠습니다!

@github-project-automation github-project-automation bot moved this to In Review in Wable-iOS Mar 14, 2025
@youz2me youz2me merged commit 98eeeca into develop Mar 14, 2025
@youz2me youz2me deleted the feat/#119-wable-components branch March 14, 2025 07:44
@github-project-automation github-project-automation bot moved this from In Review to Done in Wable-iOS Mar 14, 2025
youz2me added a commit that referenced this pull request Oct 26, 2025
[Feat] 와블 컴포넌트(액션 시트, 404, 로딩뷰, 사진 상세, CTA버튼) 구현
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 기능 또는 객체 구현 🍻 진웅 술 한잔 가온나~

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Feat] 공통 컴포넌트 구현

3 participants