Scroll UIScrollView to focused UITextField in Swift

I had a screen with multiple textfields embedded in a scrollview. When a textfield became first responder I wanted the textfield to scroll to the top of the view.

I will explain the way I used to achieve this below, (there probably are other ways, but this way worked for me).
The first thing that was required was to add the UITextFieldDelegate so that we can call the textfield protocol methods.

class ViewController: UITextFieldDelegate

Then I set the delegate of the textfield to self (the viewController that now conforms to UITextFieldDelegate)

let textField = UITextField()
textField.delegate = self

The following method is now available as we conform to UITextFieldDelegate. This will fire any time a text field gains focus.

func textFieldDidBeginEditing(_ textField: UITextField)
{
    var point = textField.frame.origin
    point.y = point.y - 5
    scrollView.setContentOffset(point, animated: true)
}

First we find the position of the textfield that now has focus and assign the CGPoint to a variable. We then adjust the y position so that there is some space at the top of the screen when the scrollview scrolls to this position. We then set the contentOffset to the point and set it to animate (to make it look nicer).

iOS taking a screenshot programatically – using Swift

On a project I am currently working on I recently had to use one screen as the background of the next screen. In order to achieve this I opted to take a screenshot of the initial screen, save it as a UIImage and then set it as the background image of the next screen.

public class func screenShotOfView(view: UIView) -> UIImage
    {
        UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size, false, 0);
        view.window!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
        let image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image
}

I added the code above to a helper class that I could call from anywhere in my app allowing any screen to pass a screenshot of itself to the next screen.

You need to ensure that you are rendering the layer of the window and not just the view so that you capture navigation and tab bars in the screen shot.

“{library} does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)”

I have been working with Xcode 7 and iOS 9 beta and updating an existing app for an iOS 9 release.
So far I have encountered a couple issues with new features introduced in iOS 9. The first, is to do with App Transport Security the second is this one. The full error is: “{library} does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64

Bitcode is one component of App Thinning. It allows Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store. By default Bitcode is enabled in Xcode so any existing libraries included in the app will need to contain bitcode, hence the error.

Read more about App Thinning here

“The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.”

I started getting this error when making network requests to our dev server after upgrading and testing our app using Xcode 7 and iOS 9.

It turns out that this is a feature introduced in iOS 9, App Transport Security. It basically requires the app to make requests to https urls. These also should be specified in the info.plist.

It is possible to switch this off and at the time of writing this post that was the easiest course of action.

<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

** This is not the advised way to deal with this error **

Have a look at Steven Peterson’s blog post going into a lot more detail about how to configure your app for App Transport Security

AFNetworking requestWithMethod:URLString: parameters:error: returns nil for URLString

I was creating a request as below to test one of my network calls.

NSMutableURLRequest *request = [self.requestSerializer
requestWithMethod:@"POST"
URLString:[NSURL URLWithString:URLString relativeToURL:self.baseURL].absoluteString
parameters:parameters
error:nil];

Annoyingly the requestSerializer would return nil for the URLString. This is the url I was expecting it to return.
{baseURL}/users/396250/bookings/33050/cancellation?reason=Bad weather

After a lot of search around for why requestSerialiser was failing on query strings, I realised I actually needed to escape the space. As soon as I did this, it worked fine.

This did reveal a bit of an architectural issue with my app and the testing as the request made within the app worked without any problems, which would suggest that at a higher level my requests are being escaped but the tests don’t seem to route through there.

Unknown class in Interface Builder file.

I was recently updating an app cerated a long time ago and I opened it in Xcode 6 hit run. Once the app launched I got an error that said “Unknown class <ClassDelegate> in Interface Builder file.

After reading through a number of suggestions of what to try, most of which were fixes for if you are using a storyboard (which I wasn’t), I found that in the didFinishLaunchingWithOption if you put [<ClassDelegate> class] then this removed the error.

“UINavigationController set unrecognized selector sent to instance” when trying to set NSString in modal view – Xcode 6

I created a new view controller embedded in a UINavigationController in my storyboard and linked it with the class. I created a action segue to a button so that when it was clicked it should present the view controller modally. When I tried to setup the segue for it and update an NSString declared in the header file of that view controller I would get an error “-[UINavigationController setCurrentSpeaker:]: unrecognized selector sent to instance 0x14c634a70

This is the code I was using to update the currentSpeaker NSString:

if ([[segue identifier] isEqualToString:@"speakerSegue"]){
        SpeakerViewController *svc = [segue destinationViewController];
        svc.currentSpeaker = thisSpeaker;
 
    }

The problem with this code is that the segue’s destinationViewController is actually the navigation controller and not the SpeakerViewController I thought it was.
I updated it to this which worked perfectly:

if ([[segue identifier] isEqualToString:@"speakerSegue"]){
        UINavigationController *navController = (UINavigationController*)[segue destinationViewController];
        SpeakerViewController *svc = (SpeakerViewController *)[navController topViewController];
        svc.currentSpeaker = thisSpeaker;
 
    }

Global variables in Roku application

I have recently started making apps for the Roku box. Roku apps use a scripting language called Brightscript.

I wanted to add a global variable into my app so that I could use a string in any function of the app. Turns out that in Brightscript you only have access to one global variable and that is ‘m‘. You are able to create properties of m. I was able to declare m.channelName = “myglobalstring” I could then use m.channelName anywhere in the app.

Setting caret (cursor) position in TinyMCE without using bookmarks

I recently had to automatically implement emoticons in my TinyMCE instance on a website. One of the requirements was to be able to type :) and have it automatically change to the emoticon.This wasn’t a huge task but the issue that followed seem to present a challenge. By default the caret was moving back to the beginning of the text rather than staying in its natural position.

The solution I found to this problem was to add an extra element along with the image that was being inserted. Then I was able to search for that element id and select it which would position the caret in the correct place. Then I would remove the element added as it was no longer required.

var placeholderMarker = $(tinyMCE.activeEditor.getBody()).find('#cursorMarker');
tinyMCE.activeEditor.selection.select(placeholderMarker.get(0) );
placeholderMarker.remove();