2015-01-18 3 views
7

Я хочу, чтобы иметь возможность открыть изображение в Swift. Это мой первый проект Swift.Подробные инструкции по использованию NSOpenPanel

@IBAction func SelectFileToOpen(sender: NSMenuItem) { 
    var openPanel = NSOpenPanel(); 
    openPanel.allowsMultipleSelection = false; 
    openPanel.canChooseDirectories = false; 
    openPanel.canCreateDirectories = false; 
    openPanel.canChooseFiles = true; 
    let i = openPanel.runModal(); 
    if(i == NSOKButton){ 
     print(openPanel.URL); 
     var lettersPic = NSImage(contentsOfURL: openPanel.URL!); 
     imageView.image = lettersPic; 

    } 
} 

Выход из моих NSLog при использовании открытой панели

Optional(file:///Users/ethansanford/Desktop/BigWriting.png) 
fatal error: unexpectedly found nil while unwrapping an Optional value 

Как я могу позволить пользователю открыть файл PNG интерес. Когда я указываю один и тот же файл в коде, все работает хорошо. Пример меня указывающий, какой файл открыть в коде, не используя открытую файловую панель и действует как пользователь:

let pictureURl = NSURL(fileURLWithPath: "///Users/ethansanford/Desktop/BigWriting.png"); 
var lettersPic = NSImage(contentsOfURL: pictureURl!); 
imageView.image = lettersPic; 

Есть проблема с форматом моего URL или что-то? Любая помощь будет оценена по достоинству.

+0

Если с моим кодом сложно найти что-то неправильное. Я был бы доволен примером, любой пример nsopenpanel используется для открытия png, который работал. Из того, что я могу сказать, существует другой способ использования nsopenpanel с помощью обработчика завершения. – jiminybob99

ответ

9

Добавить новый файл в проект (скор исходный файл) и добавьте это расширение там

Xcode 9 • Swift 4

extension NSOpenPanel { 
    var selectUrl: URL? { 
     title = "Select Image" 
     allowsMultipleSelection = false 
     canChooseDirectories = false 
     canChooseFiles = true 
     canCreateDirectories = false 
     allowedFileTypes = ["jpg","png","pdf","pct", "bmp", "tiff"] // to allow only images, just comment out this line to allow any file type to be selected 
     return runModal() == .OK ? urls.first : nil 
    } 
    var selectUrls: [URL]? { 
     title = "Select Images" 
     allowsMultipleSelection = true 
     canChooseDirectories = false 
     canChooseFiles = true 
     canCreateDirectories = false 
     allowedFileTypes = ["jpg","png","pdf","pct", "bmp", "tiff"] // to allow only images, just comment out this line to allow any file type to be selected 
     return runModal() == .OK ? urls : nil 
    } 
} 

В вашем View Controller:

class ViewController: NSViewController { 
    @IBOutlet weak var imageView: NSImageView! 
    @IBAction func saveDocument(_ sender: NSMenuItem) { 
     print("SAVE") 
    } 
    @IBAction func newDocument(_ sender: NSMenuItem) { 
     print("NEW") 
    } 
    // connect your view controller to the first responder window adding the openDocument method 
    @IBAction func openDocument(_ sender: NSMenuItem) { 
     print("openDocument ViewController") 
     if let url = NSOpenPanel().selectUrl { 
      imageView.image = NSImage(contentsOf: url) 
      print("file selected:", url.path) 
     } else { 
      print("file selection was canceled") 
     } 
    } 
} 
+0

Вы всегда должны указывать свои функции, начиная с буквы нижнего регистра. Поэтому вам следует сменить SelectFileToOpen на selectFileToOpen –

+0

. Создание файла main.swift кажется довольно сложным. очевидно, если у вас есть файл main.swift, файл AppDelegate.swift больше не работает. Мне любопытно было вы это узнали. Какие книги вы читаете? – jiminybob99

+0

Вы используете раскадровки? –

3

Хммм ... Я не вижу ничего плохого обязательно с кодом, поэтому я побежал тест этот код (выбор PNG файл на моем рабочем столе):

let openPanel = NSOpenPanel() 
openPanel.allowsMultipleSelection = false 
openPanel.canChooseDirectories = false 
openPanel.canCreateDirectories = false 
openPanel.canChooseFiles = true 
let i = openPanel.runModal() 
if(i == NSModalResponseOK){ 
    print(openPanel.URL) 
    let lettersPic = NSImage(contentsOfURL: openPanel.URL!) 
    print(lettersPic)  
} 

Что я получил:

Optional(file:///Users/jwlaughton/Desktop/flame%2012-32.png)
Optional( "NSBitmapImageRep 0x6000000a4140 Size={1440, 900} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1440x900 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x608000160cc0")>)

Который кажется OK для меня.

Может быть, этот вопрос нужно сказать:

imageView.image = lettersPic!; 

EDIT:

Так, чтобы проверить дальше, я продлил тестовый код немного:

if(i == NSOKButton){ 
    print(openPanel.URL); 

    var lettersPic = NSImage(contentsOfURL: openPanel.URL!); 
    print(lettersPic); 
    let view:NSImageView = NSImageView(); 
    view.image = lettersPic 

    print(view) 
} 

все еще работает ОК. Извините, я не смог повторить вашу проблему.

+0

Пробовал, но не добился успеха. Спасибо – jiminybob99

+0

@jwlaughton Отлично работает.Любите программный подход – eonist

1

Это код, который закончился для меня. Мне пришлось отключить доски объявлений. Мне нужно было сделать класс под названием Main. Это не следует путать со специальным классом main.swift, который заменяет appdelegate.swift. И мне также пришлось импортировать Cocoa. Тогда мне нужно было указать, что main inhereted из nsobject. Это было так, что я мог сначала установить связи между построителем интерфейса и поместить в ibactions и outlets в свой файл Main.swift.

// 
// Main.swift 
// Open 
// 
// Created by ethan sanford on 2015-01-18. 
// Copyright (c) 2015 ethan D sanford. All rights reserved. 
// 

import Foundation 
import Cocoa 


class Main: NSObject{ 

    @IBOutlet var imageWell: NSImageCell! 
    var myURL = NSURL(fileURLWithPath: "") 



    @IBAction func main(sender: AnyObject) { 


     imageWell.image = NSImage(byReferencingURL: myURL!) 

    } 


    @IBAction func open(sender: AnyObject) { 
     var openPanel = NSOpenPanel(); 
     openPanel.allowsMultipleSelection = false; 
     openPanel.canChooseDirectories = false; 
     openPanel.canCreateDirectories = false; 
     openPanel.canChooseFiles = true; 
     let i = openPanel.runModal(); 
     if(i == NSOKButton){ 
      print(openPanel.URL); 
      myURL = openPanel.URL; 
     } 


    } 


} 

Это работает немного странно, что вы должны выбрать свой файл, нажмите кнопку «Открыть». Затем нажмите кнопку, связанную с @IBAction func main(sender: AnyObject) {

+0

интересно посмотреть, как это должно было быть сделано. В основном я собираюсь снимать видео с YouTube, а курс в визуальном базовом классе я получил в старшей школе. спасибо за урок. – jiminybob99