Iam working the android and ios application using nativescript angular application.i want to access the scrollview delegates of the ios,i was accessed the scrollview delegates from the native ios following code.but it was not working:
My scrollview delegate implementation class:
// import {Injectable, EventEmitter,Output} from "#angular/core";
#ObjCClass(UIScrollViewDelegate)
export class FoodScrollDelegate extends NSObject implements UIScrollViewDelegate
{
public static ObjCProtocols = [UIScrollViewDelegate];
// #Output() yvalue:EventEmitter<any>=new EventEmitter();
private _originalDelegate:UIScrollViewDelegate;
public getY:Number=0;
constructor()
{
super();
}
public static initWithOriginalDelegate(originalDelegate:UIScrollViewDelegate):FoodScrollDelegate{
console.log("Called Method");
let delegate=<FoodScrollDelegate>FoodScrollDelegate.new();
delegate._originalDelegate=originalDelegate;
return delegate;
}
}
I have setting the scrollview delegate like this:
onScrollLoaded(args)
{
var subscroll=args.object;
var uiscrollview=subscroll.ios;
let tf=<any>this.subMenuScroll;
var newweakref=new WeakRef(uiscrollview);
const newDelegate=FoodScrollDelegate.initWithOriginalDelegate(tf._delegate);
console.log("PrintDelegate",+newDelegate);
uiscrollview.delegate=newDelegate;
}
My MenuComponet class Like this:
import { Component, OnInit, AfterViewInit,ViewChild, ElementRef} from "#angular/core";
import {Page, borderTopRightRadiusProperty} from "ui/page";
import { isIOS, isAndroid } from 'tns-core-modules/platform';
import { RadListView, ListViewEventData } from "nativescript-ui-listview";
import { RestaurentMenuModel,RestaurentSubMenuModel } from "~/app/models/restaurant";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { run } from "tns-core-modules/application/application";
import { ScrollEventData, ScrollView } from "tns-core-modules/ui/scroll-view/scroll-view";
import { RouterExtensions } from "nativescript-angular/router";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { Label } from "tns-core-modules/ui/label/label";
import { analyzeAndValidateNgModules } from "#angular/compiler";
import * as utils from "tns-core-modules/utils/utils";
import { setTimeout } from "tns-core-modules/timer";
import { EventData } from "data/observable";
import { FoodScrollDelegate } from "~/app/Utils/scroll_delegate";
declare var UITableViewCellSelectionStyle;
declare var UIView, NSMutableArray, NSIndexPath;
//declare var setShowsHorizontalScrollIndicator;
#Component({
selector:"restaurant_menu",
moduleId:module.id,
templateUrl:"./restaurant_menu.component.html",
styleUrls:["./restaurant_menu.component.css"],
})
export class RestaurantMenu implements OnInit
{
//public cartCount:Number=1;
#ViewChild("ScrollList") scrollList:ElementRef;
#ViewChild("categoryList") categoryList:ElementRef;
public AllMenuList:any;
public cartTotal:any=0;
public cartItem:any=0;
public isCartVisible=false;
incrementItem:any=0;
decrementItem:any=0;
categoryContainer:Label;
subMenuContainers:StackLayout;
offsetValue:any=0;
dummyStatus:any=0;
horizontalOffsetvalue:any=0;
lengthHorizontaloffsetLength:any=0;
public selectedIndex:Number=0;
public scrollEnabled:Boolean=false;
lastItemY:Number=0;
subMenuScroll:ScrollView;
foodScrollDelegate:FoodScrollDelegate;
_delegate:any;
constructor(private page:Page,public routerExtension:RouterExtensions)
{
}
ngOnInit()
{
this.subMenuScroll=this.page.getViewById("subMenuScroll");
//this.subMenuScroll.ios.delegate=FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
//console.log("PrintDelegate"+this.foodScrollDelegate.scrollViewDidEndDraggingWillDecelerate);
// this.foodScrollDelegate=new FoodScrollDelegate();
// this.foodScrollDelegate.yvalue.subscribe(yvalue=>{
// console.log("TheYYValue"+yvalue);
// });
}
public scrollViewDidEndDraggingWillDecelerate?(scrollView: UIScrollView, decelerate: boolean): void {
console.log("WillScrollEnd"+" "+decelerate);
}
public scrollViewDidScroll?(scrollView: UIScrollView): void {
this.getY=scrollView.contentOffset.y;
console.log("Yposition"+this.getY);
//this.yvalue.emit(this.getY);
}
onLoaded(event)
{
const scrollview = event.object;
if (scrollview.ios) {
scrollview.ios.showsHorizontalScrollIndicator = false;
}
else
{
scrollview.android.setHorizontalScrollBarEnabled(false);
}
}
onNavBtnTap()
{
this.routerExtension.backToPreviousPage();
}
}
Inside the i was implemented the delegate methods.but it was working
ObjCClass is an alternative syntax for ObjCProtocols. You may not need to do both.
The default delegate is attached after loaded event, so your delegate may be overwritten again. You will have to extend the ScrollView and override the attachNative method.
class MyScrollView extends ScrollView {
protected attachNative() {
(<any>ScrollView.prototype).attachNative.call(this);
if (isIOS) {
(<any>this)._delegate = FoodScrollDelegate.initWithOriginalDelegate((<any>this)._delegate);
this.nativeViewProtected.delegate = (<any>this)._delegate;
}
}
}
Register this MyScrollView,
registerElement("MyScrollView", () => MyScrollView);
Now you should be able to use MyScrollView instead of ScrollView in your HTML which will override the default delegate. If you wanted to override delegate for all ScrollView used in app, you could simply override the prototype chain of ScrollView conditionally on iOS.
(<any>ScrollView.prototype).originalAttachNative = (<any>ScrollView.prototype).attachNative;
(<any>ScrollView.prototype).attachNative = function () {
this.originalAttachNative();
const newDelegate = FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
this._delegate = newDelegate;
this.nativeViewProtected.delegate = newDelegate;
};
If you like to fire an event from delegate then,
scrollViewDidEndDraggingWillDecelerate(scrollView: UIScrollView, decelerate: boolean) {
const owner = (<WeakRef<ScrollView>>(<any>this._originalDelegate)._owner).get();
if (owner) {
owner.notify({
object: owner,
eventName: "dragEnd",
decelerate: decelerate
});
}
}
Now from Angular, you could listen to the event,
HTML
(dragEnd)="onDragEnd($event)"
TS
onDragEnd(event) {
console.log(event.decelerate);
}
Related
I am working on implementing Interstitial ads in my app and running into some confusion with the docs provided by Admob and the new SwiftUI app structure.
Here is the app.swift file, showing that I've implemented the GoogleMobileAds and started it in the didFinishLaunchingWithOptions method.
import SwiftUI
import GoogleMobileAds
#main
struct adamsCalcApp: App {
var calculator = Calculator()
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(calculator)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// Setup google admob instance
GADMobileAds.sharedInstance().start(completionHandler: nil)
return true
}
}
In my ContentView.swift File, I have the interstitial variable created like...
#State var interstitial: GADInterstitialAd?
Then on the main stack in the view, I call onAppear(perform: ) to load the ad, however I keep getting this error.
.onAppear(perform: {
let request = GADRequest()
GADInterstitialAd.load(withAdUnitID:"ca-app-pub-3940256099942544/4411468910",
request: request,
completionHandler: { [self] ad, error in
if let error = error {
return
}
interstitial = ad
interstitial?.fullScreenContentDelegate = self
}
)
})
"Cannot assign value of type 'ContentView' to type
'GADFullScreenContentDelegate?'"
I am feeling a bit clueless after trying a few different workarounds and trying to look up a setup that is like mine, AdMob docs still show how to implement with class ViewControllers and I would like to figure out how to do this is SwiftUI.
import SwiftUI
import GoogleMobileAds
import AppTrackingTransparency
import AdSupport
class AdsManager: NSObject, ObservableObject {
private struct AdMobConstant {
static let interstitial1ID = "..."
}
final class Interstitial: NSObject, GADFullScreenContentDelegate, ObservableObject {
private var interstitial: GADInterstitialAd?
override init() {
super.init()
requestInterstitialAds()
}
func requestInterstitialAds() {
let request = GADRequest()
request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
GADInterstitialAd.load(withAdUnitID: AdMobConstant.interstitial1ID, request: request, completionHandler: { [self] ad, error in
if let error = error {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
return
}
interstitial = ad
interstitial?.fullScreenContentDelegate = self
})
})
}
func showAd() {
let root = UIApplication.shared.windows.last?.rootViewController
if let fullScreenAds = interstitial {
fullScreenAds.present(fromRootViewController: root!)
} else {
print("not ready")
}
}
}
}
class AdsViewModel: ObservableObject {
static let shared = AdsViewModel()
#Published var interstitial = AdsManager.Interstitial()
#Published var showInterstitial = false {
didSet {
if showInterstitial {
interstitial.showAd()
showInterstitial = false
} else {
interstitial.requestInterstitialAds()
}
}
}
}
#main
struct YourApp: App {
let adsVM = AdsViewModel.shared
init() {
GADMobileAds.sharedInstance().start(completionHandler: nil)
}
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(adsVM)
}
}
Toggle the showInterstitial parameter in the AdsViewModel anywhere in the application and the advertisement will be shown.
In order to use the Admob docs with the newest SwiftUI release, you need to change this line...
.onAppear(perform: {
let request = GADRequest()
GADInterstitialAd.load(withAdUnitID:"ca-app-pub-3940256099942544/4411468910",
request: request,
completionHandler: { [self] ad, error in
if let error = error {
return
}
// Change these two lines of code
interstitial = ad
interstitial?.fullScreenContentDelegate = self
// To...
interstitial = ad
let root = UIApplication.shared.windows.first?.rootViewController
self.interstitial!.present(fromRootViewController: root!)
}
)
})
Using Skiko and Kotlin I want to make a basic animation: A 0 to 100 counter that automatically updates the text each second.
I managed to do it, but it has a problem, it is blinking each time the window repaints.
Here is the code:
import kotlinx.coroutines.*
import org.jetbrains.skija.*
import org.jetbrains.skiko.*
import javax.swing.*
public fun main() {
val window = SkiaWindow().apply {
layer.renderer = CounterRenderer()
setSize(400, 175)
isVisible = true
defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
}
GlobalScope.launch {
for (i in 0..100) {
delay(1000)
window.layer.repaint()
}
}
}
public class CounterRenderer : SkiaRenderer {
private lateinit var canvas: Canvas
private var counter = 0
override fun onInit() {
}
override fun onDispose() {
}
override fun onReshape(width: Int, height: Int) {
}
override fun onRender(canvas: Canvas, width: Int, height: Int) {
this.canvas = canvas
val typeface = Typeface.makeFromName("Roboto", FontStyle.NORMAL)
val fontSize = 30F
val font = Font(typeface, fontSize)
val paint = Paint().setColor(0XFF000000.toInt())
canvas.drawString("Counter: ${counter++}", 10F, 50F, font, paint)
}
}
I have tried to search for examples of animations with skija or skiko without success.
I would really appreciate if you could give me some examples.
After navigating the Android Compose code, especially this class:
ComposeLayer.
I finally got it to work with this code:
import kotlinx.coroutines.*
import org.jetbrains.skija.*
import org.jetbrains.skiko.*
import javax.swing.*
public fun main() {
val window = SkiaWindow().apply {
layer.renderer = CounterRenderer()
setSize(400, 175)
isVisible = true
defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
}
GlobalScope.launch(Dispatchers.Main) {
for (i in 0..100) {
delay(500)
window.layer.redrawLayer()
}
}
}
public class CounterRenderer : SkiaRenderer {
private var counter = 0
private val typeface = Typeface.makeFromName("Roboto", FontStyle.NORMAL)
private val fontSize = 30F
private val font = Font(typeface, fontSize)
private val paint = Paint().setColor(0XFF000000.toInt())
override fun onInit() {
}
override fun onDispose() {
}
override fun onReshape(width: Int, height: Int) {
}
override fun onRender(canvas: Canvas, width: Int, height: Int) {
canvas.drawString("Counter: ${counter++}", 10F, 50F, font, paint)
}
}
To run this code you need to install the specific Main Dispatcher, in this case it is by adding this to the gradle configuration:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.3.9")
I am trying to bind a delegate this is what was done
/** Delegate Proxy **/
func castOrThrow<T>(_ resultType: T.Type, _ object:Any) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}
return returnValue
}
#objc
public protocol TestEventGeneratorDelegate:class {
#objc optional func asyncEventResult(int:Int)
}
open class TestEventGenerator {
public var delegate: TestEventGeneratorDelegate?
func asyncCall() {
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in
guard let self = self else { return }
self.delegate?.asyncEventResult!(int: 0)
}
}
}
extension TestEventGenerator: HasDelegate {
public typealias Delegate = TestEventGeneratorDelegate
}
open class RxTestDelegateProxy : DelegateProxy<TestEventGenerator,TestEventGeneratorDelegate>,
DelegateProxyType,
TestEventGeneratorDelegate {
public weak private(set) var testGenerator: TestEventGenerator?
public init(testEventGenerator: ParentObject) {
self.testGenerator = testEventGenerator
super.init(parentObject: testEventGenerator, delegateProxy: RxTestDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { RxTestDelegateProxy(testEventGenerator: $0) }
}
}
extension Reactive where Base: TestEventGenerator {
public var delegate: DelegateProxy<TestEventGenerator, TestEventGeneratorDelegate> {
return RxTestDelegateProxy.proxy(for: base)
}
public var asyncEventResult: Observable<Int> {
let source = delegate.methodInvoked(#selector(TestEventGeneratorDelegate.asyncEventResult(int:)))
.map { (a) in
return try castOrThrow(Int.self,a[0])
}
return source
}
}
/** Delegate Proxy **/
Then when I use it
let testEventGenerator = TestEventGenerator()
textEventGenerator.rx.asyncEventResult.subscribe.... // subscribe here no rx found?
testEventGenerator.asyncCall() // call and wait for the observable to return to the delegate
It doesn't compile and says there is no such rx
I have to bind it because the person who wrote the API didn't use a callback to return the value but rather a delegate.
This is example of how he wrote the code and how I want to wrap it.
Is there a way to bind a delegate that requires a kick off from asyncCall()?
so I can chain it using flatmapLatest in a promiseLike way?
Thanks let me know!
I followed these tutorial:
How to convert Delegate to Observable RxSwift?
and
https://blog.ippon.fr/2018/11/13/rxswift-how-to-make-your-favorite-delegate-based-apis-reactive/
have conform to TestEventGenerator:ReactiveCompatible and that will fix it.
My kotlin code brakes when the onclick adapterPosition. I've debug the code but I'm still not sure what is going on and why is not working.
Here is my Category Adapter:
import android.content.Context
import android.content.Intent
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import com.google.android.gms.common.internal.service.Common
import com.letsbuildthatapp.kotlinmessenger.Quizz.Model.Category
import com.letsbuildthatapp.kotlinmessenger.Quizz.Model.Interface.IOnRecyclerViewItemClickListener
import com.letsbuildthatapp.kotlinmessenger.Quizz.Model.Question
import com.letsbuildthatapp.kotlinmessenger.R
class CategoryAdapter(internal var context: Context,
internal var categoryList: List<Category>):
RecyclerView.Adapter<CategoryAdapter.MyViewHolder>() {
//This is correct
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): MyViewHolder {
val itemView = LayoutInflater.from(context).inflate(R.layout.layout_category_item, parent, false)
return MyViewHolder(itemView)
}
// this is correct
override fun getItemCount(): Int {
return categoryList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.txt_category_name.text = categoryList[position].name
holder.setiOnRecyclerViewItemClickListener(object : IOnRecyclerViewItemClickListener {
override fun onClick(view: View?, position: Int) {
// this is to direct user to the question List
com.letsbuildthatapp.kotlinmessenger.Quizz.Model.Common.Common.selectedCategory = categoryList[position]
val intent = Intent(context, Question::class.java)
context.startActivity(intent)
}
})
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
internal var txt_category_name: TextView
internal var card_category: CardView
internal lateinit var iOnRecyclerViewItemClickListener: IOnRecyclerViewItemClickListener
fun setiOnRecyclerViewItemClickListener(iOnRecyclerViewItemClickListener: IOnRecyclerViewItemClickListener) {
this.iOnRecyclerViewItemClickListener = iOnRecyclerViewItemClickListener
}
init {
txt_category_name = itemView.findViewById(R.id.txt_category_name) as TextView
card_category = itemView.findViewById(R.id.card_category) as CardView
itemView.setOnClickListener(this)
}
override fun onClick(view: View?) {
iOnRecyclerViewItemClickListener.onClick(view, adapterPosition)
}
}
}
Here is the IonRecyclerViewItemClickLister
interface IOnRecyclerViewItemClickListener {
fun onClick(view: View?, position:Int)
}
I've debugged the code and it appears to work well until it reaches to this part:
override fun onClick(view: View?) {
iOnRecyclerViewItemClickListener.onClick(view, adapterPosition)
}
}
}
My question is what am I doing wrong.
Implement your interface in your activity and pass it as parameter to your Adapter. After pass it your view holder.
I'll let you with an example of my project.
My interface
MainActivity - Where I implement the Interface
My adapter
I discovered where the error was
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.txt_category_name.text = categoryList[position].name
holder.setiOnRecyclerViewItemClickListener(object : IOnRecyclerViewItemClickListener {
override fun onClick(view: View?, position: Int) {
// this is to direct user to the question List
com.letsbuildthatapp.kotlinmessenger.Quizz.Model.Common.Common.selectedCategory = categoryList[position]
val intent = Intent(context, Question::class.java)
context.startActivity(intent)
}
})
}
The error was in point to an Activity that doesn't exist.
I'm working on an OS X App and, I can't seem to get Drag and Drop to work. I've Googled a lot, but most posts about this subject are at least a few years old and none of them tells me the missing link I have in my thoughts.
Anyway, here is what I'm trying to do. I have an image somewhere on my desktop and I want the ability to drag and drop that into my Custom NSView. The custom view is a child object of a custom NSView named CircularImageView and is layer backed and only shows a circular shaped image on the screen.
Here's the code:
import Cocoa
import MCTools
#objc public protocol DragAndDropCircularImageViewDelegate {
func imageDumped(sender: AnyObject!)
}
#IBDesignable #objc public class DragAndDropCircularImageView: CircularImageView {
// This class provides the Drag And Drop Feature to the CircularImageView Class.
// MARK: New in this class
var highlight: Bool = false
public var delegate: DragAndDropCircularImageViewDelegate?
private func registerForDraggedImages() {
self.registerForDraggedTypes(NSImage.imageTypes())
}
// MARK: CircularImageView Stuff
public override var image: NSImage? {
didSet {
if let newImage = image {
delegate?.imageDumped(self)
}
}
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
self.registerForDraggedImages()
}
public override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.registerForDraggedImages()
}
public override func updateLayer() {
super.updateLayer()
if highlight == true {
}
}
// MARK: NS Dragging Destination Protocol
public override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
// When a drag enters our drop zone.
if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
if ((sender.draggingSourceOperationMask().rawValue & NSDragOperation.Copy.rawValue) > 0) {
highlight = true
self.needsLayout = true
sender.enumerateDraggingItemsWithOptions(.Concurrent, forView: self, classes: [NSPasteboardItem.self], searchOptions: [NSPasteboardURLReadingContentsConformToTypesKey: self], usingBlock: { (draggingItem, idx, stop) -> Void in
return
})
}
return NSDragOperation.Copy
}
return NSDragOperation.None
}
public override func draggingExited(sender: NSDraggingInfo?) {
// When drag exits our drop zone remove highlight of the drop zone.
println("\(self)draggingExited")
highlight = false
self.needsLayout = true
}
public override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
// Update view for hovering drop.
println("\(self)prepareForDragOperation")
highlight = false
self.needsLayout = true
// Can we accept the drop?
return NSImage.canInitWithPasteboard(sender.draggingPasteboard())
}
public override func performDragOperation(sender: NSDraggingInfo) -> Bool {
// Handle the drop data.
println("\(self)performDragOperation \(sender)")
if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
self.image = NSImage(pasteboard: sender.draggingPasteboard())
}
return true
}
// MARK: Interface Builder Stuff
}
I have seen some posts that I should be using:
self.registerForDraggedTypes([NSFilenamesPboardType])
instead of:
self.registerForDraggedTypes(NSImage.imageTypes())
But this doesn't seem to work in my case, when I'm using NSFileNamesPboardType I get the following debug message even before any of the NSDraggingDestination protocol messages have been called:
2015-05-07 11:07:19.583 CircularImageViewTest[44809:14389647] -[CircularView.DragAndDropCircularImageView copyWithZone:]: unrecognized selector sent to instance 0x608000166d80
(lldb) p 0x608000166d80
(Int) $R0 = 106102873550208
I don't understand how this works. Somewhere the frameworks try to copyWithZone on an integer? Can anyone explain this to me?
Any help would be appreciated. Thanks in advance.
Ok, the code below works. It was all caused by sender.enumerateDraggingItemsWithOptions in draggingEntered. Something goes wrong in the Apple frameworks when it is called.
import Cocoa
import MCTools
#objc public protocol DragAndDropCircularImageViewDelegate {
func imageDumped(sender: AnyObject!)
}
#IBDesignable #objc public class DragAndDropCircularImageView: CircularImageView {
// This class provides the Drag And Drop Feature to the CircularImageView Class.
// MARK: New in this class
var highlight: Bool = false
public weak var delegate: DragAndDropCircularImageViewDelegate?
private func registerForDraggedImages() {
// self.registerForDraggedTypes(NSImage.imageTypes())
self.registerForDraggedTypes([NSFilenamesPboardType])
}
// MARK: CircularImageView Stuff
public override var image: NSImage? {
didSet {
if let newImage = image {
delegate?.imageDumped(self)
}
}
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
self.registerForDraggedImages()
}
public override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.registerForDraggedImages()
}
public override func updateLayer() {
super.updateLayer()
if highlight == true {
}
}
// MARK: NS Dragging Destination Protocol
public override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
// When a drag enters our drop zone.
if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
if ((sender.draggingSourceOperationMask().rawValue & NSDragOperation.Copy.rawValue) > 0) {
highlight = true
self.needsLayout = true
}
return NSDragOperation.Copy
}
return NSDragOperation.None
}
public override func draggingExited(sender: NSDraggingInfo?) {
// When drag exits our drop zone remove highlight of the drop zone.
println("\(self)draggingExited")
highlight = false
self.needsLayout = true
}
public override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
// Update view for hovering drop.
println("\(self)prepareForDragOperation")
highlight = false
self.needsLayout = true
// Can we accept the drop?
return NSImage.canInitWithPasteboard(sender.draggingPasteboard())
}
public override func performDragOperation(sender: NSDraggingInfo) -> Bool {
// Handle the drop data.
println("\(self)performDragOperation \(sender)")
if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
self.image = NSImage(pasteboard: sender.draggingPasteboard())
self.delegate!.imageDumped(self)
}
return true
}
// MARK: Interface Builder Stuff
}