If a person presses the button 10 times, then they will hear 10 different lists of songs being played continuously. I want it to be that if a person presses 10 times, they will only be listening to one list of songs. I'm basically trying to create a reset button.
var myQueuePlayer: AVQueuePlayer?
var avItems: [AVPlayerItem] = []
func audio () {
var items: [String] = ["one", "two", "three", "four", "five"]
items.shuffle()
for clip in items {
guard let url = Bundle.main.url(forResource: clip, withExtension: ".mp3") else {
// mp3 file not found in bundle - so crash!
fatalError("Could not load \(clip).mp3")
}
avItems.append(AVPlayerItem(url: url))
//button.isHidden = true
}
}
#IBAction func didTapButton() {
audio()
if myQueuePlayer == nil {
// instantiate the AVQueuePlayer with all avItems
myQueuePlayer = AVQueuePlayer(items: avItems)
} else {
// stop the player and remove all avItems
myQueuePlayer?.removeAllItems()
// add all avItems back to the player
avItems.forEach {
myQueuePlayer?.insert($0, after: nil)
}
}
// seek to .zero (in case we added items back in)
myQueuePlayer?.seek(to: .zero)
// start playing
myQueuePlayer?.play()
}
Here is a very simple example.
This assumes 5 .mp3 files in your bundle, and 4 buttons:
Play / Restart
Pause
Resume
Shuffle and Play
connected to the #IBAction funcs:
class TestAVQueuViewController: UIViewController {
var myQueuePlayer: AVQueuePlayer?
var avItemsArray: [AVPlayerItem] = []
override func viewDidLoad() {
super.viewDidLoad()
// assuming I have 5 .mp3 files in the bundle, named:
let mySongs: [String] = [
"clip1", "clip2", "clip3", "clip4", "clip5",
]
// build the array of URLs for the song files
for clip in mySongs {
if let url = Bundle.main.url(forResource: clip, withExtension: ".mp3") {
avItemsArray.append(AVPlayerItem(url: url))
} else {
print("Could not get URL for \(clip).mp3")
}
}
if avItemsArray.count == 0 {
fatalError("Failed to get URL for ANY songs!")
}
}
func playQueue() -> Void {
// if first time
if myQueuePlayer == nil {
// instantiate the AVQueuePlayer
myQueuePlayer = AVQueuePlayer()
}
guard let player = myQueuePlayer else {
// I suppose it's possible that AVQueuePlayer() failed to instantiate
// so print a message to debug console and return
print("AVQueuePlayer failed to instantiate!")
return
}
// this will make sure the player is stopped and remove any remaining avItems
player.removeAllItems()
// every time this is called,
// loop through and reset the time on each avItem
for item in avItemsArray {
item.seek(to: .zero, completionHandler: nil)
}
// add avItems to the player
avItemsArray.forEach {
player.insert($0, after: nil)
}
// start playing
player.play()
}
#IBAction func playRestartTapped(_ sender: Any) {
playQueue()
}
#IBAction func pauseTapped(_ sender: Any) {
guard let player = myQueuePlayer, player.items().count > 0 else {
return
}
player.pause()
}
#IBAction func resumeTapped(_ sender: Any) {
guard let player = myQueuePlayer, player.items().count > 0 else {
return
}
player.play()
}
#IBAction func restartShuffledTapped(_ sender: Any) {
// shuffle the items
avItemsArray.shuffle()
playQueue()
}
}
Related
I am learning how to create a barcode scanner and would like to add highlighting (the yellow square that goes around the numbers when the camera recognizes it)
I believe I should use isHighlightingEnabled: true
But I am not sure what line to put it on in my code. Where should I be placing it and do I need to add anything to make it work?
import UIKit
import Vision
import AVFoundation
import SafariServices
#objc class CMWSTVisionReader: UIViewController {
// MARK: - Private Variables
var captureSession = AVCaptureSession()
#IBOutlet weak var cameraView: UIView!
#IBOutlet weak var barcodeResult: UILabel!
// TODO: Make VNDetectBarcodesRequest variable
lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in
guard error == nil else {
// self.showAlert(
// withTitle: "Barcode error",
// message: error?.localizedDescription ?? "error")
return
}
self.processClassification(request)
}
// MARK: - Override Functions
override func viewDidLoad() {
super.viewDidLoad()
checkPermissions()
setupCameraLiveView()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// TODO: Stop Session
captureSession.stopRunning()
}
}
extension CMWSTVisionReader {
// MARK: - Camera
private func checkPermissions() {
// TODO: Checking permissions
switch AVCaptureDevice.authorizationStatus(for: .video) {
// 1
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { [self] granted in
if !granted {
showPermissionsAlert()
}
}
// 2
case .denied, .restricted:
showPermissionsAlert()
// 3
default:
return
}
}
private func setupCameraLiveView() {
// TODO: Setup captureSession
captureSession.sessionPreset = .hd1280x720
// TODO: Add input
// 1
let videoDevice = AVCaptureDevice
.default(.builtInWideAngleCamera, for: .video, position: .back)
// 2
guard
let device = videoDevice,
let videoDeviceInput = try? AVCaptureDeviceInput(device: device),
captureSession.canAddInput(videoDeviceInput)
else {
// 3
showAlert(
withTitle: "Cannot Find Camera",
message: "There seems to be a problem with the camera on your device.")
return
}
// 4
captureSession.addInput(videoDeviceInput)
// TODO: Add output
let captureOutput = AVCaptureVideoDataOutput()
// TODO: Set video sample rate
captureOutput.videoSettings =
[kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
captureOutput.setSampleBufferDelegate(
self,
queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
captureSession.addOutput(captureOutput)
configurePreviewLayer()
// TODO: Run session
captureSession.startRunning()
}
// MARK: - Vision
func processClassification(_ request: VNRequest) {
// TODO: Main logic
// 1
guard let barcodes = request.results else { return }
DispatchQueue.main.async { [self] in
if captureSession.isRunning {
view.layer.sublayers?.removeSubrange(1...)
// 2
for barcode in barcodes {
guard
// TODO: Check for QR Code symbology and confidence score
let potentialQRCode = barcode as? VNBarcodeObservation,
potentialQRCode.confidence > 0.9
else { return }
// 3
observationHandler(payload: potentialQRCode.payloadStringValue)
}
}
}
}
// MARK: - Handler
func observationHandler(payload: String?) {
// TODO: Open it in Safari
// 1
barcodeResult.text = payload
// guard
// let payloadString = payload,
// let url = URL(string: payloadString),
// ["http", "https"].contains(url.scheme?.lowercased())
// else { return }
//
// // 2
// let config = SFSafariViewController.Configuration()
// config.entersReaderIfAvailable = true
//
// // 3
// let safariVC = SFSafariViewController(url: url, configuration: config)
// safariVC.delegate = self
// present(safariVC, animated: true)
}
}
// MARK: - AVCaptureDelegation
extension CMWSTVisionReader: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// TODO: Live Vision
// 1
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
// 2
let imageRequestHandler = VNImageRequestHandler(
cvPixelBuffer: pixelBuffer,
orientation: .right)
// 3
do {
try imageRequestHandler.perform([detectBarcodeRequest])
} catch {
print(error)
}
}
}
// MARK: - Helper
extension CMWSTVisionReader {
private func configurePreviewLayer() {
let cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
cameraPreviewLayer.videoGravity = .resizeAspectFill
cameraPreviewLayer.connection?.videoOrientation = .portrait
cameraPreviewLayer.frame = cameraView.frame
cameraView.layer.insertSublayer(cameraPreviewLayer, at: 0)
}
private func showAlert(withTitle title: String, message: String) {
DispatchQueue.main.async {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true)
}
}
private func showPermissionsAlert() {
showAlert(
withTitle: "Camera Permissions",
message: "Please open Settings and grant permission for this app to use your camera.")
}
}
// MARK: - SafariViewControllerDelegate
extension CMWSTVisionReader: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
captureSession.startRunning()
}
}
I'm trying to retrieve images from array of url..
I have this function that do the same as I won't but it doesn't work so I tried to use URLSession but didn't know how exactly to make it >>
func downloadImages(imageUrls: [String], completion: #escaping (_ images: [UIImage?]) -> Void) {
var imageArray: [UIImage] = []
var downloadCounter = 0
for link in imageUrls {
let url = NSURL(string: link)
let downloadQueue = DispatchQueue(label: "imageDowmloadQueue")
downloadQueue.sync {
downloadCounter += 1
let data = NSData(contentsOf: url! as URL)
if data != nil {
//image data ready and need to be converted to UIImage
imageArray.append(UIImage(data: data! as Data)!)
if downloadCounter == imageArray.count {
DispatchQueue.main.async {
completion(imageArray)
}
}
} else {
print("couldnt download image")
completion(imageArray)
}
}
}
}
The function I work on :
public func imagesFromURL(urlString: [String],completion: #escaping (_ images: [UIImage?]) -> Void) {
var imageArray: [UIImage] = []
var downloadCounter = 0
let downloadQueue = DispatchQueue(label: "imageDowmloadQueue")
for link in urlString {
downloadQueue.sync {
downloadCounter += 1
let dataTask = URLSession.shared.dataTask(with: NSURL(string: link)! as URL, completionHandler: { (data, response, error ) in
if error != nil {
print(error ?? "No Error")
return
}
if data != nil {
imageArray.append(UIImage(data: data! as Data)!)
if downloadCounter == imageArray.count {
completion(imageArray)
}
} else {
print("couldnt download image")
completion(imageArray)
}
} dataTask.resume()
}
}
}
i want to call the function in the collection cell and get the display the first image only from each artwork array..
//download the first image only to display it:
if artwork.ImgLink != nil && artwork.ImgLink.count > 0 {
downloadImages(imageUrls: [artwork.ImgLink.first!]) { (images) in
self.artworkImage.image = images.first as? UIImage
}
}
If you intend to use only the first available UIImage from an array of urls, you do not design a function trying to download all of them. Instead, try to download from the first url, return the downloaded UIImage if it succeeds, or continue with the second url if it fails, repeat until you get an UIImage.
Creating a DispatchQueue in a local function looks dangerous to me. A more common practice is to maintain a queue somewhere else and pass it to the function as a parameter, or reuse one of the predefined global queues using DispatchQueue.global(qos:) if you don't have a specific reason.
Be careful with sync. sync blocks the calling thread until your block finishes in the queue. Generally you use async.
Use a Int counter to control when to finish multiple async tasks (when to call the completion block) works but can be improved by using DispatchGroup, which handles multiple async tasks in a simple and clear way.
Here's two functions. Both work. firstImage(inURLs:completion:) only return the first UIImage that it downloads successfully. images(forURLs:completion:) tries to download and return them all.
func firstImage(inURLs urls: [String], completion: #escaping (UIImage?) -> Void) {
DispatchQueue.global().async {
for urlString in urls {
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
DispatchQueue.main.async {
completion(image)
}
return
}
}
}
DispatchQueue.main.async {
completion(nil)
}
}
}
// Use it.
firstImage(inURLs: artwork.ImgLink) { image in
self.artworkImage.image = image
}
func images(forURLs urls: [String], completion: #escaping ([UIImage?]) -> Void) {
let group = DispatchGroup()
var images: [UIImage?] = .init(repeating: nil, count: urls.count)
for (index, urlString) in urls.enumerated() {
group.enter()
DispatchQueue.global().async {
var image: UIImage?
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
image = UIImage(data: data)
}
}
images[index] = image
group.leave()
}
}
group.notify(queue: .main) {
completion(images)
}
}
// Use it.
images(forURLs: artwork.ImgLink) { images in
self.artworkImage.image = images.first(where: { $0 != nil }) ?? nil
}
I want my swift code to call the playSound and play the sound based for the duration of each item in array playamount. So I want the user to play the sound for the first time for 10 seconds then play the sound starting at the beginning for 20 and then the same thing for 30 seconds. So the sound always starts at the beginning each time it is called.
import UIKit; import AVFoundation
class ViewController: UIViewController {
var player: AVAudioPlayer?
func playSound() {
let url = Bundle.mainBundle().URLForResource("rock", withExtension: "mp3")!
do {
player = try AVAudioPlayer(contentsOfURL: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error as NSError {
print(error.description)
}
}
var playAmount : [Int] = [10,20,30]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class ViewController: UIViewController {
var player: AVAudioPlayer?
var currentIndex: Int = 0
func runMusicBox() {
guard !playAmount.isEmpty else { return }
currentIndex = 0
newTimerForIndex(index: 0)
}
func newTimerForIndex(index: Int) {
player?.prepareToPlay()
player?.play()
Timer.scheduledTimer(withTimeInterval: Double(playAmount[index]), repeats: false) { timer in
self.player?.stop()
if self.currentIndex + 1 < self.playAmount.count {
self.currentIndex += 1
self.newTimerForIndex(index: self.currentIndex)
} else {
self.player?.stop()
}
}
}
func playSound() {
let url = Bundle.mainBundle().URLForResource("rock", withExtension: "mp3")!
do {
player = try AVAudioPlayer(contentsOfURL: url)
guard let player = player else { return }
runMusicBox()
} catch let error as NSError {
print(error.description)
}
}
var playAmount : [Int] = [10,20,30]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Hi, can you try this code. Here I have a timer, and when one stops, then we check if we have another element in the array and will run a new timer. The Timer is working, but i didn;t check the player. if it works as expected - it should work for you
I am looking for a way to simply play audio files one after another.
AVAudioPlayer using an array seems to be the best solution. In fact, I was able to play the first element of the array using Sneak's recommendations found on this page : Here.
But I don't understand where and how to write the second call to AVAudioPlayer in order to play the second file?
The "audioPlayerDidFinishPlaying" function is not reacting. Why?
Thanks for watching.
import Cocoa
import AVFoundation
var action = AVAudioPlayer()
let path = Bundle.main.path(forResource: "test.aif", ofType:nil)!
let url = URL(fileURLWithPath: path)
let path2 = Bundle.main.path(forResource: "test2.aif", ofType:nil)!
let url2 = URL(fileURLWithPath: path2)
let array1 = NSMutableArray(array: [url, url2])
class ViewController: NSViewController
{
#IBOutlet weak var LanceStop: NSButton!
override func viewDidLoad()
{
super.viewDidLoad()
do
{
action = try AVAudioPlayer(contentsOf: array1[0] as! URL)
action.numberOfLoops = 0
action.prepareToPlay()
action.volume = 1
}catch{print("error")}
}
...
#IBAction func Lancer(_ sender: NSButton)
{
if action.isPlaying == true
{
action.stop()
action.currentTime = 0.0
LanceStop.title = "Lancer"
}
else
{
action.play()
LanceStop.title = "Stopper"
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
{
if flag == true
{
LanceStop.title = "Lancer"
}
}
}
But I don't understand where and how to write the second call to
AVAudioPlayer in order to play the second file?
So in order to play the second file, you need to write one method where you will need to initialize the audioplayer and invoke the same method inside audioplayer delegate method audioPlayerDidFinishPlaying like this:-
func playAudioFile(_ index: Int) {
do
{
action = try AVAudioPlayer(contentsOf: array1[index] as! URL)
action.numberOfLoops = 0
action.prepareToPlay()
action.volume = 1
} catch{print("error")
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
//This delegate method will called once it finished playing audio file.
//Here you can invoke your second file. You can declare counter variable
//and increment it based on your file and stop playing your file acordingly.
counter = counter + 1
playAudioFile(counter)
}
Note:- Set Audioplayer delegate to your ViewController in order to get invoke
audioPlayerDidFinishPlaying method like this.
action.delegate = self
Changed Code...
class ViewController: NSViewController, AVAudioPlayerDelegate
{
#IBOutlet weak var LanceStop: NSButton!
override func viewDidLoad()
{
super.viewDidLoad()
}
override var representedObject: Any?
{
didSet
{
// Update the view, if already loaded.
}
}
func playAudioFile(_ index: Int)
{
do
{
action = try AVAudioPlayer(contentsOf: array1[index] as! URL)
action.delegate = self
action.numberOfLoops = 0
action.prepareToPlay()
action.volume = 1
action.play()
}
catch{print("error")}
}
#IBAction func Lancer(_ sender: NSButton)
{
playAudioFile(0)
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
{
if flag == true
{
playAudioFile(1)
}
}
}
I have 2 arrays
var messages = [Message]()
var screenMessages = [screenMessage]()
I have the messages array items in a NSTableView.. when I press an IBOutlet I would like to pass the items in that row to the screenMessages array to present in another NSTableView.
My NSTableView starts like so..
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell", owner: self) as? secondviewTableCell
let mess = messages[row]
I've tried a number of ways of appending the screenMessages with the messages[row] but I can't put my finger on it. If anyone could demonstrate or point me in the right direction that would be brilliant.
Thank you.
Added more detail:
Screen one looks like so and when pressing the add button it should then pass that data from that row into screen twos tableview..
Screen two:
My View for screen one is as:
import Firebase
import Cocoa
var messages = [Message]()
var screenMessages = [screenMessage]()
class secondVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
#IBOutlet weak var tableView: NSTableView!
#IBOutlet weak var screenRefreshBtn: NSButton!
#IBOutlet weak var refreshButton: NSButton!
var senderImageUrl: String!
var ref: Firebase!
var messagesRef: Firebase!
func setupFirebase() {
messagesRef = Firebase(url: "https://url.firebaseio.com/screenmessages")
messagesRef.queryLimitedToLast(25).observeEventType(FEventType.ChildAdded, withBlock: { (snapshot) in
let text = snapshot.value["text"] as? String
let sender = snapshot.value["senderName"] as? String
let imageUrl = snapshot.value["profileImageURL"] as? String
let MediaType = snapshot.value["MediaType"] as! String
let fileUrl = snapshot.value["fileUrl"] as? String
let message = Message(text: text, sender: sender, imageUrl: imageUrl, MediaType: MediaType, fileUrl: fileUrl)
messages.append(message)
let screenmessage = screenMessage(text: text, sender: sender, imageUrl: imageUrl, MediaType: MediaType, fileUrl: fileUrl)
screenMessages.append(screenmessage)
switch MediaType{
case "TEXT":
print("text message")
case "PHOTO":
print("photo message")
default:
print("default")
}
self.tableView.reloadData()
})
}
override func viewDidLoad() {
super.viewDidLoad()
setupFirebase()
}
// MARK: - Table View
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return messages.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell", owner: self) as? secondviewTableCell
let mess = messages[row]
if mess.text() == nil {
result?.textField?.alphaValue = 0
result!.sendertextView.stringValue = mess.sender()
let url = NSURL(string: mess.fileUrl()!)!
// Download task:
// - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects.
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
// if responseData is not null...
if let data = responseData{
// execute in UI thread
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let photo = NSImage(data: data)!
result?.mediaPhoto.image = photo
})
}
}
task.resume()
} else {
result!.textField!.stringValue = mess.text()!
result!.sendertextView.stringValue = mess.sender()
}
return result
}
#IBAction func addtablerow(object: NSButton) {
let row = tableView.rowForView( object as NSView )
if ( row > -1 ) {
}
}
And my second screen is:
import Cocoa
class screenVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var addedObserver = false
#IBOutlet weak var tableView: NSTableView!
override func viewDidLoad() {
super.viewDidLoad()
refreshObs()
clearObs()
self.tableView.backgroundColor = NSColor.clearColor()
if let window = self.view.window {
// custom window here
window.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
} else {
addedObserver = true
self.addObserver(self, forKeyPath: "view.window", options: [.New, .Initial], context: nil)
}
}
func refreshList(notification: NSNotification){
self.tableView.alphaValue = 0
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
animateViewRefresh()
tableView.scrollToEndOfDocument(self)
}
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return screenMessages.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell2", owner: self) as? screenviewTableCell
let mess = screenMessages[row]
result?.senderLabel.stringValue = mess.sender()
if mess.text() != nil {
result?.messageTextView.stringValue = mess.text()!
let url = NSURL(string: mess.imageUrl()!)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
result?.avatarImage.image = NSImage(data: data)
})
}}
task.resume()
} else {
result?.messageTextView.alphaValue = 0
let mess = screenMessages[row]
let url = NSURL(string: mess.fileUrl()!)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let photo = NSImage(data: data)!
result?.mediaPhoto.image = photo
})
}
}
let url2 = NSURL(string: mess.imageUrl()!)!
let task2 = NSURLSession.sharedSession().dataTaskWithURL(url2) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
result?.avatarImage.image = NSImage(data: data)
})
}}
task.resume()
task2.resume()
}
return result
}
// MARK : Animate
func animateView(notification: NSNotification){
NSAnimationContext.runAnimationGroup({ (context) in
context.duration = 2
self.tableView.animator().alphaValue = 0
screenMessages.removeAll()
}, completionHandler: { () -> Void in
})}
func animateViewRefresh(){
NSAnimationContext.runAnimationGroup({ (context) in
context.duration = 4
self.tableView.animator().alphaValue = 1
}, completionHandler: { () -> Void in
})}
func refreshObs(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(screenVC.refreshList(_:)), name:"refreshMyTableView", object: nil)
}
func clearObs(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(screenVC.animateView(_:)), name:"clearMyTableView", object: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if let window = self.view.window {
// custom window here
window.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
window.titlebarAppearsTransparent = true
window.movableByWindowBackground = true
window.opaque = true
window.backgroundColor = NSColor.clearColor()
}
}
deinit {
if addedObserver {
self.removeObserver(self, forKeyPath: "view.window")
}
}
}
I have tried a number of things such as 'screenMessages += messages(row)' and appending to add that row to the screenMessages array but I've had no luck.
Am I going about this in the right way or is there a better way of doing so?
Thank you.
To append an element from one array to another array just write
let index = index of element you need
let message = messages[index]
screenMessages.append(message)
If message is not the same type as the contents of the screenMessages array you will need to convert it, I would need more details of the types to help with that.
If you are having trouble passing the data to another ViewController I would need more information on the current architecture to give good advice, but for example you might define a protocol MessageDelegate that one of the controllers implements and the other has as a property.
update
If you update your data array for a table and want the new information to appear remember to call reloadData on the UITableView