Commit c77cdb6b authored by Aral Balkan's avatar Aral Balkan

Initial add.

parents
.DS_Store
# Via https://github.com/github/gitignore/blob/master/Objective-C.gitignore
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
Carthage
\ No newline at end of file
git "git@source.ind.ie:project/handle.git" ~> 2.0
\ No newline at end of file
git "git@source.ind.ie:project/handle.git" "v2.0.12"
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:GlobalTouchNotifications/GlobalTouchNotifications.xcodeproj">
</FileRef>
<FileRef
location = "group:GlobalTouchNotificationsDemo-iOS/GlobalTouchNotificationsDemo-iOS.xcodeproj">
</FileRef>
</Workspace>
//
// GlobalTouchNotifications.h
//
// Created by Aral Balkan on 28/01/2016.
// Copyright © 2016 Aral Balkan. All rights reserved.
//
// Released with ♥ by Ind.ie under the MIT License.
//
#import <UIKit/UIKit.h>
//! Project version number for GlobalTouchNotifications.
FOUNDATION_EXPORT double GlobalTouchNotificationsVersionNumber;
//! Project version string for GlobalTouchNotifications.
FOUNDATION_EXPORT const unsigned char GlobalTouchNotificationsVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <GlobalTouchNotifications/PublicHeader.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
\ No newline at end of file
//
// Global Touch Notifications
//
// Singleton: Broadcasts global touch notifications from the main window of the app.
//
// Usage:
//
// import GlobalTouchNotifications
//
// // Initialise the singleton if necessary
// GlobalTouchNotifications.sharedInstance
//
// // Register for global touch notification
// handle(GlobalTouchNotification.named(.TouchesBegan)
// {
// /* with */ notification in
//
// // Handle it here.
// }
//
// Created by Aral Balkan on 28/01/2016.
// Copyright © 2016 Aral Balkan. All rights reserved.
//
import UIKit
import Handle
public enum GlobalTouchNotification:String
{
case TouchesBegan
case TouchesEnded
case TouchesCancelled
case TouchesEstimatedPropertiesUpdated
public static func named(notification:GlobalTouchNotification) -> String
{
return notification.rawValue
}
}
public class GlobalTouchNotifications
{
/// Singleton
public class var sharedInstance:GlobalTouchNotifications
{
struct Static
{
static let instance:GlobalTouchNotifications = GlobalTouchNotifications()
}
return Static.instance
}
init()
{
let mainWindow = UIApplication.sharedApplication().windows[0]
let globalTapGestureRecognizer = GlobalTapGestureRecognizer()
globalTapGestureRecognizer.cancelsTouchesInView = false
mainWindow.addGestureRecognizer(globalTapGestureRecognizer)
}
}
class GlobalTapGestureRecognizer: UITapGestureRecognizer
{
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
{
post(GlobalTouchNotification.named(.TouchesBegan), from: self, with: ["touches": touches, "event": event])
super.touchesBegan(touches, withEvent: event)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent)
{
post(GlobalTouchNotification.named(.TouchesEnded), from: self, with: ["touches": touches, "event": event])
super.touchesEnded(touches, withEvent: event)
}
override func touchesCancelled(touches: Set<UITouch>, withEvent event: UIEvent)
{
post(GlobalTouchNotification.named(.TouchesCancelled), from: self, with: ["touches": touches, "event": event])
super.touchesCancelled(touches, withEvent: event)
}
override func touchesEstimatedPropertiesUpdated(touches: Set<NSObject>) {
post(GlobalTouchNotification.named(.TouchesEstimatedPropertiesUpdated), from: self, with: ["touches": touches])
super.touchesEstimatedPropertiesUpdated(touches)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
//
// AppDelegate.swift
// GlobalTouchNotificationsDemo-iOS
//
// Created by Aral Balkan on 28/01/2016.
// Copyright © 2016 Aral Balkan. All rights reserved.
//
// Released with ♥ by Ind.ie under the MIT License.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
return true
}
}
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="GlobalTouchNotificationsDemo_iOS" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
//
// PopoverTableViewController.swift
//
// Created by Aral Balkan on 28/01/2016.
// Copyright © 2016 Aral Balkan. All rights reserved.
//
// Released with ♥ by Ind.ie under the MIT License.
//
import UIKit
class PopoverTableViewController: UITableViewController
{
let data =
[
"Lazarus (David Bowie)",
"",
"Look up here, I'm in heaven",
"I've got scars that can't be seen",
"I've got drama, can't be stolen",
"Everybody knows me now",
"",
"Look up here, man, I'm in danger",
"I've got nothing left to lose",
"I'm so high, it makes my brain whirl",
"Dropped my cell phone down below",
"Ain't that just like me?",
"",
"By the time I got to New York",
"I was living like a king",
"Then I used up all my money",
"I was looking for your ass",
"",
"This way or no way",
"You know I'll be free",
"Just like that bluebird",
"Now, ain't that just like me?",
"",
"Oh, I'll be free",
"Just like that bluebird",
"Oh, I'll be free",
"Ain't that just like me?"
]
init() {
// Overriding this method prevents other initializers from being inherited.
// The super implementation calls init:nibName:bundle:
// so we need to redeclare that initializer to prevent a runtime crash.
super.init(style: UITableViewStyle.Plain)
self.modalPresentationStyle = .Popover
self.preferredContentSize = CGSizeMake(400, 400)
}
// This needs to be implemented (enforced by compiler).
required init(coder aDecoder: NSCoder)
{
// Or call super implementation
fatalError("NSCoding not supported")
}
// Need this to prevent runtime error:
// fatal error: use of unimplemented initializer 'init(nibName:bundle:)'
// for class 'TestViewController'
// I made this private since users should use the no-argument constructor.
private override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)
{
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.modalPresentationStyle = .Popover
self.preferredContentSize = CGSizeMake(400, 400)
}
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "regularCell")
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return data.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("regularCell", forIndexPath: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
//
// Demonstrates basic usage of Global Touch Notifications to display
// a pop-over that points to a link in a WKWebView.
//
// Created by Aral Balkan on 27/01/2016.
// Copyright © 2016 Aral Balkan. All rights reserved.
//
// Released with ♥ by Ind.ie under the MIT License.
//
import UIKit
import WebKit
import GlobalTouchNotifications
import Handle
class ViewController: UIViewController, WKNavigationDelegate, UIPopoverPresentationControllerDelegate
{
var webView:WKWebView!
var lastTouch: UITouch?
var popoverViewController: UIViewController!
var globalTouchesBeganHandler: NotificationHandler?
override func viewDidLoad()
{
super.viewDidLoad()
GlobalTouchNotifications.sharedInstance
globalTouchesBeganHandler = globalTouchesBeganHandler ?? handle(GlobalTouchNotification.named(.TouchesBegan))
{
/* with */ notification in
guard let
userInfo = notification.userInfo,
touches = userInfo["touches"] as? Set<UITouch>,
_ = userInfo["event"] as? UIEvent
else
{
fatalError("Could not unwrap userInfo dictionary for global touches.")
}
self.lastTouch = touches.first
}
webView = WKWebView(frame: self.view.frame)
webView.navigationDelegate = self
self.view.addSubview(webView)
webView.loadHTMLString("<head><meta name='viewport' content='width=device-width; initial-scale=1.0'><style>body {margin-top: 40px; background-color: #eee;}</style></head><h1>Hello</h1><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p><p>This is <a href='#'>a link</a></p>.", baseURL: nil)
popoverViewController = PopoverTableViewController()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "scrollViewTouchesBegan:", name: "ScrollViewTouchesBegan", object: nil)
}
func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
print(navigationAction)
if let lastTouch = lastTouch
{
print ("I know what you touched last summer.")
guard let myPopoverPresentationController = popoverViewController.popoverPresentationController else { fatalError("Couldn’t get popover presentation controller") }
myPopoverPresentationController.permittedArrowDirections = .Any
myPopoverPresentationController.sourceView = self.view
myPopoverPresentationController.delegate = self
let locationInView = lastTouch.locationInView(self.view)
print(locationInView)
myPopoverPresentationController.sourceRect = CGRect(x: locationInView.x, y: locationInView.y, width: 0.0, height: 10.0)
self.presentViewController(popoverViewController, animated: true, completion: nil)
}
decisionHandler(.Allow)
}
// UIPopoverPresentationControllerDelegate
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
#!/bin/sh
# Colours
successColour='\e[1;37;42m' # White on green
failColour='\e[1;37;41m' # White on red
regularColour='\e[0m'
if [ -d Carthage ]; then
# The Carthage folder exists, we’re reasonably sure that the
# installation script was run: Let’s open the workspace.
open GlobalTouchNotifications.xcworkspace
printf "\n${successColour}Workspace launched in Xcode.${regularColour}\n\nTo play with the framework, build and run the iOS demonstration app in the workspace that just opened in Xcode.\n\n"
else
# The Carthage folder does not exist, inform the person that they