asdfadsfadf

임혜정·2024년 8월 14일
0
post-custom-banner

ㅇㅇ

import UIKit
import SnapKit

// MARK: - Protocols

protocol LearningElementProtocol: UIView {
    var elementType: LearningElementType { get }
    func interact()
}

protocol LearningElementFactory {
    func createElement(ofType type: LearningElementType, withContent content: Any) -> LearningElementProtocol
}

// MARK: - Enums

enum LearningElementType {
    case text
    case quiz
    case codeEditor
    case interactiveDiagram
}

// MARK: - Concrete Learning Elements

class TextElement: UIView, LearningElementProtocol {
    let elementType: LearningElementType = .text
    private let textView: UITextView
    
    init(content: String) {
        textView = UITextView()
        textView.text = content
        textView.isEditable = false
        super.init(frame: .zero)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        addSubview(textView)
        textView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
    }
    
    func interact() {
        // 텍스트 하이라이팅 등의 인터랙션
    }
}

class QuizElement: UIView, LearningElementProtocol {
    let elementType: LearningElementType = .quiz
    private let questionLabel: UILabel
    private let answerButtons: [UIButton]
    
    init(question: String, answers: [String]) {
        questionLabel = UILabel()
        questionLabel.text = question
        answerButtons = answers.map { answer in
            let button = UIButton(type: .system)
            button.setTitle(answer, for: .normal)
            return button
        }
        super.init(frame: .zero)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        addSubview(questionLabel)
        questionLabel.snp.makeConstraints {
            $0.top.leading.trailing.equalToSuperview().inset(8)
        }
        
        let stackView = UIStackView(arrangedSubviews: answerButtons)
        stackView.axis = .vertical
        stackView.spacing = 8
        addSubview(stackView)
        stackView.snp.makeConstraints {
            $0.top.equalTo(questionLabel.snp.bottom).offset(16)
            $0.leading.trailing.bottom.equalToSuperview().inset(8)
        }
    }
    
    func interact() {
        // 퀴즈 답변 처리
    }
}

class CodeEditorElement: UIView, LearningElementProtocol {
    let elementType: LearningElementType = .codeEditor
    private let codeTextView: UITextView
    private let runButton: UIButton
    
    init(initialCode: String) {
        codeTextView = UITextView()
        codeTextView.text = initialCode
        codeTextView.font = UIFont.monospacedSystemFont(ofSize: 14, weight: .regular)
        
        runButton = UIButton(type: .system)
        runButton.setTitle("Run Code", for: .normal)
        
        super.init(frame: .zero)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        addSubview(codeTextView)
        addSubview(runButton)
        
        codeTextView.snp.makeConstraints {
            $0.top.leading.trailing.equalToSuperview().inset(8)
            $0.height.equalTo(200)
        }
        
        runButton.snp.makeConstraints {
            $0.top.equalTo(codeTextView.snp.bottom).offset(8)
            $0.trailing.bottom.equalToSuperview().inset(8)
            $0.height.equalTo(44)
        }
    }
    
    func interact() {
        // 코드 실행 로직
    }
}

// MARK: - Learning Element Factory

class LearningElementFactory: LearningElementFactory {
    func createElement(ofType type: LearningElementType, withContent content: Any) -> LearningElementProtocol {
        switch type {
        case .text:
            guard let textContent = content as? String else {
                fatalError("Invalid content for text element")
            }
            return TextElement(content: textContent)
        case .quiz:
            guard let quizContent = content as? (question: String, answers: [String]) else {
                fatalError("Invalid content for quiz element")
            }
            return QuizElement(question: quizContent.question, answers: quizContent.answers)
        case .codeEditor:
            guard let codeContent = content as? String else {
                fatalError("Invalid content for code editor element")
            }
            return CodeEditorElement(initialCode: codeContent)
        case .interactiveDiagram:
            fatalError("Interactive diagram not implemented")
        }
    }
}

// MARK: - Test View Controller

class TestViewController: UIViewController {
    private let scrollView = UIScrollView()
    private let contentView = UIView()
    private let elementFactory: LearningElementFactory
    private var learningElements: [LearningElementProtocol] = []
    
    init() {
        self.elementFactory = LearningElementFactory()
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        createLearningElements()
    }
    
    private func setupViews() {
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        
        scrollView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
        
        contentView.snp.makeConstraints {
            $0.edges.equalToSuperview()
            $0.width.equalTo(view)
        }
    }
    
    private func createLearningElements() {
        let elementConfigs: [(LearningElementType, Any)] = [
            (.quiz, (question: "프랑스의 수도는?", answers: ["런던", "베를린", "파리", "마드리드"])),
            (.codeEditor, "")
        ]
        
        var previousElement: UIView?
        
        for (type, content) in elementConfigs {
            let element = elementFactory.createElement(ofType: type, withContent: content)
            learningElements.append(element)
            contentView.addSubview(element)
            
            element.snp.makeConstraints {
                if let previousElement = previousElement {
                    $0.top.equalTo(previousElement.snp.bottom).offset(20)
                } else {
                    $0.top.equalToSuperview().offset(20)
                }
                $0.leading.trailing.equalToSuperview().inset(20)
            }
            
            previousElement = element
        }
        
        if let lastElement = previousElement {
            lastElement.snp.makeConstraints {
                $0.bottom.equalToSuperview().offset(-20)
            }
        }
    }
}
profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️
post-custom-banner

0개의 댓글