簡體   English   中英

如何使用NSTimer在UIView中繪制

[英]How to Draw in a UIView with NSTimer

我嘗試開發的應用程序的一個部分需要顯示一組圖像,而在顯示周期內用戶無需與手機交互。 用戶可以啟動顯示順序,但無需告訴手機何時停止。 該應用還需要能夠在每個顯示周期之間捕獲圖像。 我的意思是電話會顯示圖像,然后捕獲照片並保存,然后顯示下一張圖像,循環繼續進行。

我對圖像捕獲部分有很好的了解,但是我正在努力如何以上述方式顯示我的圖像集。 我知道實現此目標的困難之一是iPhone在顯示周期上更新視圖並在執行時編譯所有代碼,因此很難讓兩者互相等待。

我嘗試使用NSTimer調用UIView來更新我的特定圖像,但是該圖像無法正確繪制。 我正在使用Core Graphics以越來越高的頻率繪制條形或白色和黑色。 我認為創建和播放具有正確序列模式的電影是行不通的,因為我還需要每次顯示模式時都必須告訴iPhone捕獲圖像。

任何想法或建議,不勝感激!

我的UIViewController:

import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate {

// MARK: Properties
var orientation = "Vertical"
var numberOfBarPairs = UInt64(1)
var maximumNumberOfBarPairs = UInt64()
var binaryPattern = BinaryPattern()
var timer = NSTimer()

// Hide the status bar so the image displayed is full screen
var statusBarIsHidden = true

override func viewDidLoad() {
    super.viewDidLoad()
}

// MARK: Actions
@IBAction func displayBinaryPattern(sender: UIButton) {
    // Initiate the phase display

    // Capture the view's frame size and location
    let viewWidth = view.frame.width
    let viewHeight = view.frame.height
    //let viewSize = CGFloat(20)
    let viewOrigin = view.frame.origin

    // Set the frame that displays the binary patterns
    let frame = CGRectMake(viewOrigin.x, viewOrigin.y, viewWidth, viewHeight)

    // Set maximum number of bar pairs based on frame size
    maximumNumberOfBarPairs = 128 //Int(viewSize)/2

    // Instance a binary pattern and add it as a subview to the main view
    binaryPattern = BinaryPattern(frame: frame)

    // set display interval
    let displayInterval = 5.0

    // Set a timer to call drawBarPairs every interval
    timer = NSTimer.scheduledTimerWithTimeInterval(displayInterval, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
}

func updateView() {
    numberOfBarPairs = numberOfBarPairs*2
    print("\(orientation), \(numberOfBarPairs)")

    view.addSubview(binaryPattern)

    // Cal the draw view
    binaryPattern.orientation = orientation
    binaryPattern.numberOfBarPairs = numberOfBarPairs

    // Stop the display when we reach a termination condition
    if numberOfBarPairs == maximumNumberOfBarPairs && orientation == "Horizontal" {
        // Stop the timer
        timer.invalidate()
    }

    // Change the orientaiton of the bar pairs when the number counter reaches the maximum
    if numberOfBarPairs == maximumNumberOfBarPairs && orientation == "Vertical" {
        orientation = "Horizontal"
        numberOfBarPairs = 0
    }
  }
}

我的UIView繪制模式:

import UIKit

class BinaryPattern: UIView {

// MARK: Properties
var numberOfBarPairs: UInt64 {
    didSet {
        print("Bars Set")
        setNeedsDisplay()
    }
}

var orientation: String {
    didSet {
        print("orientation set")
        setNeedsDisplay()
    }
}

override init(frame: CGRect) {
    self.numberOfBarPairs = 1
    self.orientation = "Vertical"
    super.init(frame: frame)
}

required init(coder aDecoder: NSCoder) {
    self.numberOfBarPairs = 1
    self.orientation = "Vertical"
    super.init(coder: aDecoder)!
}

override func drawRect(rect: CGRect) {

    // Obtains the current graphics context. Think of a graphics context as a canvas. In this case, the canvas is the View that we will be working with, but there are other types of contexts, such as an offscreen buffer that we later turn into an image. Note that contexts are stateful, or a value will remain that value until it is set with a method.
    let context = UIGraphicsGetCurrentContext()

    // Disable anti-aliasing, so pixel boundarys are shown jagged
    CGContextSetShouldAntialias(context, false)

    // Query the view frame size to draw the binary pattern within
    let frameHeight: CGFloat = 256
    let frameWidth: CGFloat = 256

    // Define white and black colors
    let blackColor: UIColor = UIColor.blackColor()
    let whiteColor: UIColor = UIColor.whiteColor()

    // Determine if bars should be vertical or horizontal
    if self.orientation == "Horizontal" {
        let barWidth = frameWidth
        let barHeight = frameHeight/CGFloat(2*self.numberOfBarPairs)

        // Generate the bar pairs and fill them with appropriate colors
     //   for bar in 1...self.numberOfBarPairs {
     //       let yOrigin1 = 2*(CGFloat(bar)-1)*barHeight
     //       let yOrigin2 = (2*CGFloat(bar)-1)*barHeight
     //       let xOrigin: CGFloat = 0

        let xOrigin: CGFloat = 0
        let yOrigin1: CGFloat = barHeight
        let yOrigin2: CGFloat = 0

            CGContextSetFillColorWithColor(context, blackColor.CGColor)
            CGContextFillRect(context, CGRectMake(xOrigin, yOrigin1, barWidth, barHeight))

            CGContextSetFillColorWithColor(context, whiteColor.CGColor)
            CGContextFillRect(context, CGRectMake(xOrigin, yOrigin2, barWidth, barHeight))
       // }
    }
    else {
        // Calculate the width of each bar by dividing the outer frame width by twice the number of bar pairs
        let barWidth = frameWidth/CGFloat(2*self.numberOfBarPairs)
        let barHeight = frameHeight

        print("Bar Width: \(barWidth), Bar Height: \(barHeight)\n")

        // Generate the bar pairs and fill them with appropriate colors
        for bar in 1...self.numberOfBarPairs {
        //    let xOrigin1 = 2*(CGFloat(bar)-1)*barWidth
            let xOrigin2 = (2*CGFloat(bar)-1)*barWidth
            let yOrigin: CGFloat = 0

            print("x Origin: \(xOrigin2)")

        //let xOrigin1 = barWidth
        //let xOrigin2: CGFloat = 50
        //let yOrigin: CGFloat = 0
            //CGContextSetFillColorWithColor(context, blackColor.CGColor)
            //CGContextFillRect(context, CGRectMake(xOrigin1, yOrigin, barWidth, barHeight))

            CGContextSetFillColorWithColor(context, whiteColor.CGColor)

            CGContextFillRect(context, CGRectMake(xOrigin2, yOrigin, barWidth, barHeight))

        }
    }
  }
}

計時器應調用視圖的setNeedsDisplay。 然后,視圖的drawRect將繪制視圖的當前狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM