【问题标题】:Change UIImageView UIImage during Loop Execution在循环执行期间更改 UIImageView UIImage
【发布时间】:2015-12-01 23:03:39
【问题描述】:

我有一个将视频用作 AVURLAsset 并按时间间隔剪切视频的功能。我也有 UIImageview IBOutlet 称为 previewImageView 我希望图像在函数执行时发生变化。该函数在 viewDidLoad 中调用。 previewImageView 似乎仅在函数完成执行后才设置。下面是我的代码

func getImagesAtInterval(url: NSURL){

    let asset : AVURLAsset = AVURLAsset(URL: url, options: nil)
    let duration : CMTime = asset.duration
    let totalTime = Int(CMTimeGetSeconds(duration) * 1000)
    let assetGenerator : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)

    imageSet = [UIImage]()
    var value = 0

    for var i : Int = 0; i < totalTime; i+=200 {

        let time : CMTime = CMTimeMake(Int64(value), 1000)
        var imageRef : CGImageRef!
        do {
            imageRef = try assetGenerator.copyCGImageAtTime(time, actualTime: nil)
        } catch let error as NSError {
            print("Image generation failed with error \(error)")
        }
        if let image : UIImage? = UIImage(CGImage: imageRef){
            dispatch_async(dispatch_get_main_queue()) {

//I would like to see the images in the previewImageView 
//change as the loop operates.
                self.previewImageView.image = image
            }
            imageSet.append(image!)
        }           
        value += 200
    }
}

我已尝试按照 resourceenter link description here 中的建议进行操作

【问题讨论】:

  • UIKit 会延迟屏幕更新,以便在控制权传递回运行循环后立即完成所有操作。请改用CADisplayLink,这将调用您在屏幕更新时提供的方法。

标签: ios swift


【解决方案1】:

您需要使图像无效才能立即刷新。 只需调用 UIView 的setNeedsDisplay() 函数即可。

dispatch_async(dispatch_get_main_queue()) 
{
  self.previewImageView.image = image
  self.previewImageView.setNeedsDisplay()
}

【讨论】:

  • 感谢您的回复,虽然它似乎不起作用,也许我没有给足够的时间来绘制图像?我希望在生成图像时, previewImageView 的图像也会发生变化,直到循环结束。
  • 对不起,我更新了我的答案。它应该是函数 setNeedsDisplay 。干杯。
  • 还是不行,请看一下更新后的问题和链接,告诉我你的想法,干杯
【解决方案2】:

改用CADisplayLink,它将尝试与屏幕刷新同步。

这是一些 Objective-C 代码,我将把它作为练习留给读者将其转换为 Swift。

// call this method when you want to start updates
- (void)startUpdates
{
    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doFrame)];
    _displayLink.frameInterval = 1;
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

// I'll let you guess
- (void)stopUpdates
{
    [_displayLink invalidate];
    _displayLink = nil;
}

// In this method, do any needed updates.
// Note that it will not necessarily be called every single frame,
// so check actual time to decide what to display
- (void)doFrame
{
}

【讨论】:

  • 感谢您的回复,我将代码转换为 swift 但似乎没有用。我在进入 getImagesAtInterval 函数时调用了 startUpdating,在循环(外部)之后调用了 stopUpdating。在 doframe 中,我将 previewImageView 图像设置为 imageSet.last,因为 imageSet 是一个 uiimages 数组。
  • 那行不通。所有这些都发生在同一个线程上,因此很明显,如果您一直在线程上占用 CPU,则不会发生其他任何事情。您需要检索图像并在 doFrame 中显示它们
  • @DrPatience,如果答案对您有所帮助,请随时投票和/或接受它。
【解决方案3】:

我通过在 viewDidLoad 的后台线程中调用 getImageAtInterval 方法并在 UIThread 中调用“previewImageView.image = image”解决了这个问题 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2011-12-18
    • 1970-01-01
    • 2018-08-17
    • 2012-01-31
    • 2017-07-20
    • 1970-01-01
    相关资源
    最近更新 更多