Trying to implement "Swipe to Delete" API for UICollectionViewListCell.
I'm writing in Objective-C
the compiler is not auto-completing the code.
Any reasons? example code?
Swift example:
let listConfig = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
listConfig.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in
guard let self = self else { return nil }
let action = UIContextualAction(style: .normal, title: "Done!", handler: actionHandler)
return UISwipeActionsConfiguration(actions: [action])
}
Any code example for Objective C?
Related
I have a MacOS app that is a registered custom URL handler.
I'm trying to make it show a specific NSViewController if the app is started via the url handler or the regular window and ViewController if no parameters are used.
In my AppDelegate.swift I have this:
func application(_ application: NSApplication, open urls: [URL]) {
AppDelegate.externalCaller = true;
NSApp.hide(self)
let url: URL = urls[0];
// Process the URL.
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true);
let method = components?.host;
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if (method == "DO_STH") {
// do something with no window
NSApplication.shared.windows.last?.close();
} else if (method == "DO_STH_2") {
// do something with no window
NSApplication.shared.windows.last?.close();
} else if (method == "PROCESS_STUFF") {
// Show window
DispatchQueue.main.async {
let mainStoryboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil);
let restoringViewController = mainStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("restoringData")) as! RestoringViewController;
if let window = NSApp.mainWindow {
window.contentViewController = restoringViewController;
}
NSApp.activate(ignoringOtherApps: true);
AppDelegate.restoreData();
}
}
}
}
}
The problem is that by the time NSApp.hide(self) runs, there's already a window visible with the default viewController, creating some flickering effect.
What's the best way to make the app start without any visible window by default and only show the window if it wasn't started with any URL parameter and later on demand if a specific URL parameter exists?
Unchecking "Is initial Controller" and adding this to AppDelegate solved my issue
func applicationDidFinishLaunching(_ notification: Notification) {
if (!AppDelegate.externalCaller) {
showWindow();
}
}
func showWindow() {
let mainStoryboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil);
let windowController = mainStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("MainWindowController")) as! NSWindowController;
windowController.showWindow(self);
}
My code is trying to download some JSON data and save it to an array, then loop through the array and create a button for each item. I am having trouble assigning my function to the buttons for giving them functionality. Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//connect to website
let SongArray: Array<Any>
let url = URL(string:"*******")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil
{
print("error")
}
else
{
if let content = data
{
do
{
//download JSON data from php page, display data
let SongArray = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! [[String]]
print(SongArray)
//Make buttons with JSON array
var buttonY: CGFloat = 20
for song in SongArray {
let SongButton = UIButton(frame: CGRect(x: 50, y: buttonY, width: 250, height: 30))
buttonY = buttonY + 50 // 50px spacing
SongButton.layer.cornerRadius = 10 //Edge formatting for buttons
SongButton.backgroundColor = UIColor.darkGray //Color for buttons
SongButton.setTitle("\(song[0])", for: UIControlState.normal) //button title
SongButton.titleLabel?.text = "\(song[0])"
SongButton.addTarget(self,action: #selector(songButtonPressed(_:)), for: UIControlEvents.touchUpInside) //button press / response
self.view.addSubview(SongButton) // adds buttons to view
}
}
catch
{
}
}
}
}
task.resume()
}
} //close viewDidLoad
func songButtonPressed(_sender:UIButton!) { // function for buttons
if sender.titleLabel?.text == "\("Song[0]")" {
print("So far so good!!")
}
}
I am getting an error on the line with SongButton.addTarget...
the error says 'Use of Unresolved Identifier "SongButtonPressed"' even though its declared right after the viewDidLoad function.
Since you declared the selector SongButtonPressed(_:) it's (note the underscore)
func SongButtonPressed(_ sender: UIButton) { // no implicit unwrapped optional !!
By the way the proper selector syntax is #selector(SongButtonPressed(_:))
Two notes:
.mutableContainers has no effect in Swift at all. Omit the parameter. And delete the line let SongArray: Array<Any>. You should get an unused warning.
Functions, methods and variables are supposed to start with a lowercase letter.
I am trying to implement the action from notification. And so far I am able to trigger the right delegate functions, but after tapping the app is not brought to the foreground.
Relevant code:
#available(iOS 10.0, *)
func registerCategory() -> Void{
print("register category")
let callNow = UNNotificationAction(identifier: "call", title: "Call now", options: [])
let clear = UNNotificationAction(identifier: "clear", title: "Clear", options: [])
let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "IDENT123", actions: [callNow, clear], intentIdentifiers: [], options: [])
let center = UNUserNotificationCenter.currentNotificationCenter()
center.setNotificationCategories([category])
}
#available(iOS 10.0, *)
func scheduleNotification(event : String, interval: NSTimeInterval) {
print("schedule ", event)
let content = UNMutableNotificationContent()
content.title = event
content.body = "body"
content.categoryIdentifier = "CALLINNOTIFICATION"
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
let identifier = "id_"+event
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.currentNotificationCenter()
center.addNotificationRequest(request) { (error) in
}
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
completionHandler([.Badge, .Alert, .Sound])
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
let notification: UNNotification = response.notification
let UUID = notification.request.content.userInfo["UUID"] as! String
switch (response.actionIdentifier) {
case "COMPLETE":
UNUserNotificationCenter.currentNotificationCenter().removeDeliveredNotificationsWithIdentifiers([UUID])
case "CALLIN":
let call = Call()
CalendarController.sharedInstance.fetchMeetingByUUID(UUID, completion: { (thisMeeting) -> Void in
if(!CallIn.Yield(thisMeeting).ConferenceCallNumber.containsString("None")){
call._call(thisMeeting)
}else{
//will open detail view, in case that no number were detected
NSNotificationCenter.defaultCenter().postNotificationName("OpenDetailViewOfMeeting", object: self, userInfo: ["UUID":UUID])
}
})
UNUserNotificationCenter.currentNotificationCenter().removeDeliveredNotificationsWithIdentifiers([UUID])
default: // switch statements must be exhaustive - this condition should never be met
log.error("Error: unexpected notification action identifier: \(UUID)")
}
completionHandler()
}
I am able to hit the delegate function didReceiveNotificationResponse() with a breakpoint, and it does some actions that I put there, but not in a way that is expected (It has to start a device-call, instead it just dismisses notifications list, and nothing happens, however when I manually open the app again, the call starts as if there is no permission to open the app from notification).
I found out the reason myself, so this might be helpful to someone in the future. The answer turned out to be quite simple. When creating an action of the notification, there is this parameter: options. When you register category, you need to put it either way .Foreground or .Destructive like this:
func reisterCategory () {
let callNow = UNNotificationAction(identifier: NotificationActions.callNow.rawValue, title: "Call now", options: UNNotificationActionOptions.Foreground)
let clear = UNNotificationAction(identifier: NotificationActions.clear.rawValue, title: "Clear", options: UNNotificationActionOptions.Destructive)
let category = UNNotificationCategory.init(identifier: "NOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])
let center = UNUserNotificationCenter.currentNotificationCenter()
center.setNotificationCategories([category])
}
I am hoping someone can help me. I trying to use SIOSocket with a Swift project.
I am using the example at https://github.com/MegaBits/SIOSocket/issues/30 which seems to work, but i want to be able to declare a socket as a var like the Objective-C project example at https://github.com/MegaBits/WorldPin. so i can use it in else where in the code to call emit.
I assume i am not understanding the Obj-C block and Swift closure fundamentals and the use of self or the need to declare the var as block but can’t seem to wrap my head around it. Any help will be much appreciated.
SIOSocket is on Github
Objective-C code:
#property SIOSocket *socket;
[SIOSocket socketWithHost: #"http://localhost:3000" response: ^(SIOSocket *socket)
{
self.socket = socket; //I Want to do this in swift
__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
weakSelf.socketIsConnected = YES;
[weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};
[self.socket on: #"join" callback: ^(SIOParameterArray *args)
{
[weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
}];
[self.socket on: #"update" callback: ^(SIOParameterArray *args)
{
NSString *pinData = [args firstObject];
etc etc …
Swift Code:
private func connectToHost() {
SIOSocket.socketWithHost(host, reconnectAutomatically: true, attemptLimit: 0, withDelay: 1, maximumDelay: 5, timeout: 20, response: {
socket in
self.socket = socket // This gives me a use of unresolved identifier self error
socket.onConnect = {
println("Connected to \(host)")
socket.emit("add user", args: [username])
}
socket.on("login", callback: {(AnyObject data) -> Void in
println(["login": data])
socket.emit("new message", args: [message])
})
socket.onDisconnect = {
println("Disconnected from \(host)")
}
})
}
Your code should work, make sure you have all the right types and optional types, make sure socket is a read-write variable by defining it with var and not with let.
Try defining the closure before the method call by using let response: (SIOSocket) -> Void = {...}.
Try changing it to this:
SIOSocket.socketWithHost(host, reconnectAutomatically: true, attemptLimit: 0, withDelay: 1, maximumDelay: 5, timeout: 20, response: {(socket: SIOSocket) in
self.socket = socket // This gives me a use of unresolved identifier self error
//...
})
I changed socket in to (socket: SIOSocket) in
I'm new to xcode. I would like to convert below objective c code to swift equivalent.
ActionStringCancelBlock cancel = ^(ActionSheetStringPicker *picker) {
NSLog(#"Block Picker Canceled");
};
Thanks in advance.
This is the swift equivalent:
let cancel: ActionStringCancelBlock = { (picker: ActionSheetStringPicker) in
NSLog("Block Picker Canceled")
}
Suggested reading: Closures
You can probably just do:
let cancel: ActionStringCancelBlock = { (picker: ActionSheetStringPicker!) in
println("Block Picker Canceled")
return
}
but you might get away with:
let cancel: ActionStringCancelBlock = {
println("Block Picker Canceled")
}