Scroll View 란 무엇인가?

  • Scroll View를 사용하면 문서의 텍스트나 보이는 영역보다 큰 이미지 모음과 같은 콘텐츠를 탐색
  • 사람들이 스와이프하고, 더블탭을 하고, 드래그하고, 탭하고, 줌아웃을 때, Scroll View는 제스처를 따르며, 자연스럽게 느껴지는 방식으로 콘텐츠를 드러내거나 확대
  • Scroll View 자체는 모양이 없지만, 사람들이 상호 작용할 때 일시적인 스크롤 인디케이터를 표시
  • Scroll View는 페이징 모드에서 작동하도록 구성할 수도 있으며, 스크롤은 현재 페이지를 이동하는 대신 완전히 새로운 콘텐츠 페이지 표시

지켜야 할 점

  • 줌 동작을 적절하게 지원할것
    • 앱에서 의미가 있다면, 사람들이 줌아웃을 하거나 두 번 탭하여 확대/축소하도록 하세요.
    • 확대/축소를 활성화할 때, 의미가 있는 최대 및 최소 스케일 값을 설정하세요. 예를 들어, 한 문자가 화면을 채울 때까지 텍스트를 확대하는 것은 대부분의 앱에서 의미가 없습니다.
  • Scroll View가 페이징 모드에 있을 때 페이지 컨트롤 요소를 표시하는 것을 고려할 것
    • 페이지 컨트롤은 사용 가능한 페이지, 화면 또는 기타 콘텐츠 수를 표시하고 현재 볼 수 있는 페이지를 나타냅니다.
    • Scroll View로 페이지 컨트롤을 표시하는 경우, 혼란을 피하기 위해 같은 축의 스크롤 인디케이터를 비활성화하십시오. Page Controls ← HIG 문서 참고
  • Scroll View 안에 또다른 Scroll View를 중첩하지 말것
    • 제어하기 어려운 예측할 수 없는 인터페이스가 생성됩니다.
  • 일반적으로, 한 번에 하나의 Scroll View를 표시할 것
    • 사람들은 종종 스크롤할 때 큰 스와이프 제스처를 하며, 같은 화면에서 중첩된 Scroll View와 상호 작용하는 것을 피하기 어려울 수 있습니다.
    • 한 화면에 두 개의 스크롤 뷰를 넣어야 하는 경우, 한 가지 제스처가 두 View 모두에 영향을 미치지 않도록 다른 방향으로 스크롤하도록 허용하는 것을 고려하십시오.
    • 예를 들어 iPhone이 세로 방향일 때 주식 앱에 회사별 정보 위로 수직으로 스크롤되는 주식 시세 표시가 표시됩니다.

UIScrollView ← 공식문서

Image View 란 무엇인가?

  • Image View는 투명하거나 불투명한 배경 위에 단일 이미지 또는 애니메이션 이미지 시퀀스를 표시
  • Image View 내에서 이미지를 늘리거나, 확장하거나, 크기에 맞게 조정하거나, 특정 위치에 고정될 수 있다.
  • Image View는 기본적으로 상호 작용하지 않는다 ( 각각 고유의 이미지를 타나냄, 다른 이미지에 영향 X )

지켜야 할점

  • 가능하다면, 애니메이션 시퀀스의 모든 이미지가 일관되게 크기인지 확인할것
  • 이미지는 뷰에 맞게 미리 조정되어야 하므로 시스템이 스케일링을 할 필요가 없고, 시스템이 스케일링을 수행해야 하는 경우, 모든 이미지가 크기와 모양이 같을 때 원하는 결과를 얻기 쉽다

UIImageView ← 공식문서 참고

문제

 

풀이 코드

struct Deque<T> {
    private var elements: [T] = []
    
    public var size: Int {
        return elements.count
    }
    
    public var empty: Int {
        return elements.isEmpty ? 1 : 0
    }
    
    public func front() -> T? {
        return self.elements.first
    }
    
    public func back() -> T? {
        return self.elements.last
    }
    
    public mutating func push_front(_ element: T) {
        return elements.insert(element, at: 0)
    }
    
    public mutating func push_back(_ element: T) {
        return elements.append(element)
    }
    
    public mutating func pop_front() -> T? {
        return elements.isEmpty ? nil : elements.removeFirst()
    }
    
    public mutating func pop_back() -> T? {
        return elements.isEmpty ? nil : elements.removeLast()
    }
}

let N = Int(readLine()!)!
var intQueue = Deque<Int>()

for _ in 0..<N {
    let inputs = readLine()!.split(separator: " ")
    switch inputs[0] {
    case "push_front":
        intQueue.push_front(Int(inputs[1])!)
    case "push_back":
        intQueue.push_back(Int(inputs[1])!)
    case "pop_front":
        print(intQueue.pop_front() ?? -1)
    case "pop_back":
        print(intQueue.pop_back() ?? -1)
    case "size":
        print(intQueue.size)
    case "empty":
        print(intQueue.empty)
    case "front":
        print(intQueue.front() ?? -1)
    default:
        print(intQueue.back() ?? -1)
    }
}

 

풀이 과정

Front 와 Back 을 구분하는것 이외에는 큐 문제와 완전 똑같았다,

채점결과 한번 틀렸는데

front 와 back 개념을 잘못 설정했다 .. 머쓱 ^^

 

back 함수들을 추가하여

insert(item, at: index) 를 통해 첫 요소에 값을 넣어 push_front 를 구성 하였고,

removeLast 함수를 사용해 마지막 요소를 제거해 주었다

문제

 

풀이 코드

var result = [Int]()
let inputs = readLine()!.split(separator: " ")
var num: [Int] = Array(1...Int(inputs[0])!)
var idx = Int(inputs[1])! - 1

while true {
    result.append(num.remove(at: idx))
    if num.isEmpty { break }
    idx = (idx + Int(inputs[1])! - 1) % num.count
}
print("<\(result.map({ String($0)}).joined(separator: ", "))>")

 

풀이 과정

문제를 이해하는데 그림을 그려야 했다.. 그래서 발로 그린듯한 그림을..

이렇게 원형으로 앉아있을때 K번 순으로 제거하는 문제였다

K번째를 셀때, 제거된 자리는 건너뛰고 세어야 한다!! 

 

코드에서 inputs[0] 에는 N 이,  inputs[1] 에는 K 가 들어간다.

 

그리고 나서 규칙을 찾기위해 열심히.. 그림을 그렸다

처음 idx 는 K - 1 ( 인덱스는 0부터 시작하기 때문!! ) 가 되고,

이후로 제거할때 마다 idx 를 바꿔줘야 하는데, 어떻게 바꿀지를 그리면서 고민한 결과 규칙을 찾았다!

 

1. 우선 idx 인덱스 요소를 제거한다

2. 현재 idx 의 값에 K-1 을 더한후, 제거후 남은 배열의 갯수로 나눈 나머지로 재설정한다 ( idx = (idx + (k-1)) % Array.count )

3. 무한 루프로 돌되, 제거후 배열이 비어 있는 상태가 되면 루프를 종료시킨다!

 

알고나면 간단한 문제였다..

이래서 그리면서 생각하는게 중요한가봄..

문제

 

풀이 코드

struct Queue<T> {
    private var elements: [T] = []
    
    public var size: Int {
        return elements.count
    }
    
    public var empty: Int {
        return elements.isEmpty ? 1 : 0
    }
    
    public func front() -> T? {
        return self.elements.first
    }
    
    public func back() -> T? {
        return self.elements.last
    }
    
    public mutating func push(_ element: T) {
        return elements.append(element)
    }
    
    public mutating func pop() -> T? {
        return elements.isEmpty ? nil : elements.removeFirst()
    }
}

let N = Int(readLine()!)!
var intQueue = Queue<Int>()

for _ in 0..<N {
    let inputs = readLine()!.split(separator: " ")
    switch inputs[0] {
    case "push":
        intQueue.push(Int(inputs[1])!)
    case "pop":
        print(intQueue.pop() ?? -1)
    case "size":
        print(intQueue.size)
    case "empty":
        print(intQueue.empty)
    case "front":
        print(intQueue.front() ?? -1)
    default:
        print(intQueue.back() ?? -1)
    }
}

 

풀이 과정

Queue에 대한 개념을 학습하고, 이를 Swift 로 구현한 후 문제를 보니 쉽게 다가왔다,

Queue를 정의한 struct를 이용해서 문제를 풀 수 있었다.

 

그런데 풀이코드와 같은 Queue의 구조를 쓰게되면 메모리 효율이 떨어지기 때문에 다른 방법으로 큐를 구현하여 풀었더니

분명 TastCase 모두 정답이 나왔고, 문제없이 잘 출력 되었는데 틀렸다는 채점결과를 얻게되었다.

아직까지 뭐가 문제인지 모르겠다,, 이것저것 테스트를 해보았지만 정상적으로 값이 출력되었는데 도저히 모르겠다.

 

혹시나 해서 메모리 효율을 무시하고 그냥 원래의 방식대로 풀었더니 맞았다고 나왔다..

출력 결과는 같은데 도대체 뭐가 다른건지.. 도저히 모르겠다..

 

문제의 코드

struct Queue<T> {
    private var elements: [T?] = []
    private var head = 0
    
    public var size: Int {
        var numberOfNonNilValues = 0
        for case .some in elements { numberOfNonNilValues += 1 }
        return numberOfNonNilValues
    }
    
    public var empty: Int {
        return elements.isEmpty ? 1 : 0
    }
    
    public func front() -> T? {
        return self.elements.first ?? nil
    }
    
    public func back() -> T? {
        return self.elements.last ?? nil
    }
    
    public mutating func push(_ element: T) {
        return elements.append(element)
    }
    
    public mutating func pop() -> T? {
        guard head < elements.count, let element = elements[head] else { return nil }
        elements[head] = nil
        head += 1
        
        if head > (elements.count / 3) {
            elements.removeFirst(head)
            head = 0
        }
        return element
    }
}

let N = Int(readLine()!)!
var intQueue = Queue<Int>()
var element: Int?

for _ in 0..<N {
    let inputs = readLine()!.split(separator: " ")
    switch inputs[0] {
    case "push":
        intQueue.push(Int(inputs[1])!)
    case "pop":
        print(intQueue.pop() ?? -1)
    case "size":
        print(intQueue.size)
    case "empty":
        print(intQueue.empty)
    case "front":
        print(intQueue.front() ?? -1)
    default:
        print(intQueue.back() ?? -1)
    }
}

+ Recent posts