본문 바로가기

전체 글

(385)
카메라 데이터 수신을 위한 AVCaptureSession AVCaptureSession 과 AVCaptureVideoDataOutput은 생성시 별도 설정이 없으므로, 미리 생성해 둔다. Input의 경우 device 객체가 필요하므로, device 생성 이후에 설정. output의 경우 device에 따라 픽셀 포맷이 변경되므로, 관련 프로퍼티 추가. var captureSession: AVCaptureSession = .init() var videoDataOutput: AVcaptureVideoDataOutput = .init() var currentDevice: AVCaptureDevice? var preview: AVCaptureVideoPreviewLayer? var deviceFormat: AVCaptureDevice.Format? var prefe..
collection view 에서 load more 처리 목록을 더 읽어와 하단에 추가하는 경우엔 스크롤 관련 이벤트에 따라 그냥 읽어서 붙이면 간단한데.. 채팅이나 메신저와 같이 이전 목록을 불러와 기족 목록 상단에 추가하는 경우 스크롤 관련 설정이 조금 더 필요. 스크롤 위치에 따라 더 읽기 작업 시작 연속으로 호출되면 안되므로, 플래그를 두어서 한번만 호출되도록 처리 func scrollViewdidScroll(_ scrollView: UIScrollView) { guard scrollView.contentSize.height > scrollView.bounds.height else { return } if scrollView.contentOffset.y
UIPanGestureRecognizer 슬라이드 다운 뷰 액션시트와 같이 하단에 표시되는 뷰를 pan gesture를 사용해 에니메이션 시키고, 사라지게 하는 예. class DefaultTouchPanGestureRecognizer: UIPanGestureRecognizer { var touchPosition: CGPoint? override func touchesBegan(_ touches: Set, with event: UIEvent) { super.touchesBegan(touches, with: event) touchPosition = touches.first?.location(in: view) } } class SampleViewController: UIViewController { private var panGesture: DefaultTouchP..
UITextView 사이즈 조정 및 글자 제한, placeholder 제한된 숫자만 입력을 제공하는 경우 UITextViewDelegate 의 아래 메쏘드 구현. 최대수보다 1 크게 체크하는데.. 한글과 같이 마지막에 조합이 이루어지는 경우와 특정 글자가 넘어갈 경우만 알림을 보여주기 위함. func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let currentText = textView.text else { return true } let newLength = currentText.count + text.count - range.length if newLength > maxCharacterCount { // r..
UITextView 자동 높이 특정 사이즈까지는 높이가 커지다가 해당 사이즈 부터는 스크롤로 전환 초기에는 사이즈가 증가해야 하기에 텍스트뷰의 isScrollEnabled = false 로 설정 높이 제약을 특정 사이즈 이하(lessThanOrEqual)로 설정 let textView: UITextView = .init() func setup() { . . textView.isScrollEnabled = false . . addSubview(textView) } func setupLayout() { textView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ textView.heightAnchor.constraint(lessThanOrE..
오디오유닛 레벨 계산 마이크에서 전달된 오디오 데이터의 렌더 이벤트 static let onGetPlayoutData: AURenderCallback = {( inRefCon: UnsafeMutableRawPointer, ioActionFlags: UnsafeMutablePointer, inTimeStamp: UnsafePointer, inBusNumber: UInt32, inNumFrames: UInt32, ioData: Optional) -> OSStatus in let myObject = unsafeBitCast(inRefCon, to: MyObject.self) // 매번 계산할지 특정 간격으로 계산을 수행할지는 ui의 표시 형태에 따라 진행한다 // 미리 설정한 오디오 세션의 ioBufferDuration 에 따라 ..
Image, PixelBuffer CMSampleBuffer -> CVPixelBuffer let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBuffer -> CIImage let ciimage = CIImage(cvPixelBuffer: pixelBuffer) CIImage -> CGImage context 생성은 비용이 높으므로, 미리 생성해 두고 사용 let context = CIContext(options: nil) let cgImage = context.createCGImage(ciimage, from: ciimage.extent)! CIImage, CGImage -> UIImage let uiImage = UIImage(CIImage: ciImage) l..
아이폰 로컬 화면 공유 : Broadcast Extension 화면 전체를 녹화하기 위해서는 ReplayKit 과 Broadcast Extention 이 필요. 별도 프로세스로 동작하므로, 앱과 extention 간의 커뮤니케이션 필요.( app group, xpc or socket 등) broadcast extension 은 메모리 사용량에 50M 제약이 있으므로, 캡처되는 샘플 프레임의 사이즈와 프레임 레이트등을 고려해서 구성해야 한다. 비디오 사이즈에 따라 인코딩이나 전송단 버퍼링 등에서 50메가를 넘는 경우가 많아 실시간이나 부드러운 프레임 레이트의 제공에는 한계가 있다. 제한 메모리 사용량을 넘으면 익스텐션이 바로 종료되어 버리므로, 오디오까지 인코딩하는 경우 메모리 관리가 빡빡한 편. 익스텐션 앱에서 브로드캐스트 익스텐션 타겟 추가 익스텐션 타겟이 생성되..