rFlex / SCRecorder

iOS camera engine with Vine-like tap to record, animatable filters, slow motion, segments editing
Apache License 2.0
3.06k stars 583 forks source link

Autolayout in overlayView #223

Open tonyxiao opened 9 years ago

tonyxiao commented 9 years ago

For some reason if I have an overlay view that lays out its subviews using autolayout it doesn't seem to work. Subviews (of the overlay) frame still remain exactly where they were even though the parent view's frame has been changed. I made sure that there's no ambiguous layout anywhere.

I'm not exactly sure why this doesn't work yet. But a few ideas. It seems that layoutIfNeeded is being called from background thread, which can be a problem because UIKit is not thread-safe.

mjgaylord commented 9 years ago

@tonyxiao can you post your code? I am using autolayout with SCRecorder without any issues.

tonyxiao commented 9 years ago

There's no much code. Here's the layout in interface builder

screen shot 2015-10-05 at 5 13 48 pm

And there's the code to export video. Overlay is the same as the overlay that's highlighted in screenshot above.

    class func exportVideo(session: SCRecordSession, filter: SCFilter? = nil, overlay: UIView? = nil) -> Future<NSURL, NSError> {
        let promise = Promise<NSURL, NSError>()
        let exporter = SCAssetExportSession(asset: session.assetRepresentingSegments())
        exporter.videoConfiguration.filter = filter
        exporter.videoConfiguration.overlay = overlay
        exporter.outputFileType = AVFileTypeMPEG4
        exporter.outputUrl = session.outputUrl
        exporter.exportAsynchronouslyWithCompletionHandler {
            if let error = exporter.error {
                promise.failure(error)
            } else {
                promise.success(exporter.outputUrl!)
            }
        }
        return promise.future
    }

At runtime in the debugger I see that frame of the overlay view gets changed to match the size of the pixel buffer and that layoutIfNeeded gets called. However the subviews of the overlay view do not get laid out according to autolayout after layoutIfNeeded is called. I tried replacing layoutIfNeeded with layoutSubviews to no avail.

        overlay.frame = CGRectMake(0, 0, CVPixelBufferGetWidth(outputPixelBuffer), CVPixelBufferGetHeight(outputPixelBuffer));
        [overlay layoutIfNeeded];
mjgaylord commented 9 years ago

@tonyxiao Ah, I didn't realise you were trying to export your overlay view. This might not be possible with your particular view hierarchy especially if it is complex, but perhaps you can do everything using manual layout and implement your layout logic in the layoutSubviews method of your overlay view. I've found it often resolves issues like this.

Alternatively, if you know what is causing the issue and how to resolve it in the SCRecorder code, then submit a pull request.

HackShitUp commented 6 years ago

@tonyxiao were you able to resolve this issue?

tonyxiao commented 6 years ago

@HackShitUp i don't think so. Though it's been so long I don't feel I have a lot of context anymore.