Archive for the ‘ iOS ’ Category

JSQMessagesViewController – Messages UI

On the app I’m currently working on I’ve got a messaging portion.

Originally I implemented a basic TableView with a TextField to add a message.

Then I searched for Messages UI frameworks and came across JSQMessagesViewController

There’s a Sample project you can look into – JSQMessagesDemo.

It comes as a Cocoapod:

I’m using 7.3.4.


Create a new Xcode project.

Open terminal at that folder

pod init

add

pod 'JSQMessagesViewController'

then

pod install

Open the Xcode ‘#App.xcworkspace’

Create a View Controller that inherits

: JSQMessagesViewController<UIActionSheetDelegate, JSQMessagesComposerTextViewPasteDelegate>
#import <JSQMessagesViewController/JSQMessagesViewController.h>
#import "DemoData.h"
@class MessageViewController;
@protocol MessageViewControllerDelegate <NSObject>
- (void)didDismissMessagesViewController:(MessageViewController *)vc;
@end

Add some properties and methods

@property (weak, nonatomic) id<MessageViewControllerDelegate> delegateModal;
@property (strong, nonatomic) DemoData *data;
- (void)receiveMessagePressed:(UIBarButtonItem *)sender;
- (void)closePressed:(UIBarButtonItem *)sender;

I didn’t bother with any of the settings so commented these checks out.


I couldn’t find the Accessory Button Delegate to add to my View Controller.

#import "JSQMessagesViewAccessoryButtonDelegate.h"
<JSQMessagesViewAccessoryButtonDelegate>

For testing create a new class for your demo data.

DemoData.h

@interface DemoData : NSObject
@property (strong, nonatomic) NSMutableArray *messages;
@property (strong, nonatomic) NSDictionary *users;
@property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
@property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
@end


DemoData.m

Create some test Users.

- (instancetype)init
{
    self = [super init];
    if (self) {  
        [self loadFakeMessages];
        self.users = @{ @"1" : @"Alex",
                        @"2" : @"Sam",
                        @"3" : @"Kev",
                        @"4" : @"Ray" };
        JSQMessagesBubbleImageFactory *bubbleFactory = [[JSQMessagesBubbleImageFactory alloc] init];       
        self.outgoingBubbleImageData = [bubbleFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
        self.incomingBubbleImageData = [bubbleFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleGreenColor]];
    }
    return self;
}

Create the Fake Messages

- (void)loadFakeMessages { ... }

We can use this back in our MessageViewController.m

#pragma mark - View lifecycle
  • viewDidLoad
  • viewWillAppear
  • viewDidAppear

Since I’m not using Avatars add this to viewDidLoad

self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero; self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;

Also return nil in ‘avatarImageDataForItemAtIndexPath’

- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
    ...
    return nil;
}

Implement these other methods.

#pragma mark - Custom menu actions for cells
#pragma mark - Actions
#pragma mark - JSQMessagesViewController method overrides
#pragma mark - JSQMessages CollectionView DataSource

Choose a user here

  • senderId
  • senderId
#pragma mark - UICollectionView DataSource
#pragma mark - UICollectionView Delegate
#pragma mark - Custom menu items
#pragma mark - JSQMessages collection view flow layout delegate
#pragma mark - Adjusting cell label heights
#pragma mark - Responding to collection view tap events
#pragma mark - JSQMessagesComposerTextViewPasteDelegate methods
#pragma mark - JSQMessagesViewAccessoryDelegate methods

Changing some settings

I didn’t want the Add Attachments button.

viewDidLoad

self.inputToolbar.contentView.leftBarButtonItem = nil;

Now just to swap out the messages to my XMPP Server…

Advertisements

MapKit

So I’ve been learning MapKit this week.

It’s been a fun new framework to look into.

Create an Annotation so you can have custom properties.

@interface Annotation : NSObject<MKAnnotation>

Add a category to it so you have a way of telling what it is.

This could be an enum.

In the Delegate method

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation

You can use the category to set up some properties like a button and the pin colour.

I’m wondering if the “reuseIdentifier” should be unique here too?

You’ve added a button, now how to call it?

You could add a target and action

[rightButton addTarget:## action:## forControlEvents:UIControlEventTouchUpInside];

but instead you can use the “calloutAccessoryControlTapped” delegate method.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

As this isn’t a  “MKAnnotation” like “viewForAnnotation” but an “MKAnnotationView” we need to get the annotation from the passed view.

if ([view.annotation isKindOfClass:[OotAnnotation class]]) { ... }

Then call pfs,

Then in the “prepareForSegue” you need to get the Annotation when you click on a Pin button, this can be cast from the Sender

if ([view.annotation isKindOfClass:[OotAnnotation class]]) { ... }
Annotation *annotation = (Annotation *)[(MKAnnotationView *)sender annotation];

You could then pass your custom Location details via the ViewController. (See code)

Searching for locations to add to the map:

MKLocalSearchRequest

Adding a route, need to investigate this more.

MKPolyline

All Code

UIBarButtonItem Image and Text

I want to add an image and text to a BarButtonItem but can’t in IB.

 

I looked into EdgeInsets but couldn’t get them to work with the image.

 

I’d also like to shrink the image

// https://stackoverflow.com/a/18853240/2895831
UIView *rightButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 110, 50)];

UIImage *buttonImage = [UIImage imageNamed:@"LocationArrow"];
//UIEdgeInsets edgeInsets = UIEdgeInsetsMake(50, 50, 50, 50);
//UIImage *buttonImage = [[UIImage imageNamed:@"LocationArrow"] resizableImageWithCapInsets:edgeInsets];
//UIImage(CGImage: originalImage!.CGImage!, scale: 5, orientation: originalImage!.imageOrientation)
// https://stackoverflow.com/a/38523085/2895831
buttonImage = [UIImage imageWithCGImage:buttonImage.CGImage
 scale:4//CGImageGetHeight(buttonImage.CGImage)/2
 orientation:UIImageOrientationUp];

UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
rightButton.backgroundColor = [UIColor clearColor];
rightButton.frame = rightButtonView.frame;
[rightButton setImage:buttonImage forState:UIControlStateNormal];
[rightButton setTitle:NSLocalizedString(@"My Location", nil) forState:UIControlStateNormal];
rightButton.tintColor = [UIColor whiteColor];
rightButton.autoresizesSubviews = YES;
rightButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
rightButton.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
[rightButton addTarget:self action:@selector(myLocationAction:) forControlEvents:UIControlEventTouchUpInside];

CGFloat padding = 10.0f;
[rightButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, padding)];
//[rightButton setContentEdgeInsets:UIEdgeInsetsMake(0, 0, 0, padding)];
//[rightButton setContentEdgeInsets:UIEdgeInsetsMake(padding, padding, padding, padding)];
//[rightButton setImageEdgeInsets:UIEdgeInsetsMake(padding, 0, padding, 0)]; //0, padding, 0, padding
//[rightButton setImageEdgeInsets:UIEdgeInsetsMake(padding, padding, padding, padding)];

[rightButtonView addSubview:rightButton];

UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:rightButtonView];
self.navigationItem.rightBarButtonItem = rightBarButton;

 

Image

[UIImage imageWithCGImage:buttonImage.CGImage scale:4 orientation:UIImageOrientationUp];

Pick your method to scale

CGImageGetHeight(buttonImage.CGImage)/2

Or

CGImageGetWidth(...)/DESIREDWIDTH

 

IB

There is the handy

Bar Item

Image Inset

 

UIButton VerticalLayout

https://stackoverflow.com/a/22621613/2895831

I added some buttons into a UIStackView but the image overlaps the button.

I modified the contentEdgeInsets

CGFloat inset = (self.frame.size.height - totalHeight)/2;
self.contentEdgeInsets = UIEdgeInsetsMake(inset, 0.0f, inset, 0.0f);

 

 

Pollen Today Widget

I want a today Widget to show pollen count.

I downloaded:

Clarityn’s Pollen Forecast UK by Bayer HealthCare AG

https://appsto.re/gb/tPFfw.i

They have a website

http://www.claritynallergy.co.uk/allergyforecast/?zip=X

It doesn’t have the Widget I wanted so I started looking for an API.


POST http://www.claritynallergy.co.uk/webservice/allergyforecast.php

Header

Accept: application/json

Body

Form URL-Encoded

zip=NE11EE

Response

"{\"Durham & Newcastle\":{\"1499515201\":{\"precipitation\":8,\"maxTemp\":21,\"minTemp\":16,\"pollenLevel\":\"H\",\"humidity\":83,\"windSpeed\":7,\"weatherCode\":7,\"uvIndex\":5,\"pollenType\":\"Grass\"},\"1499601600\":{\"precipitation\":18,\"maxTemp\":18,\"minTemp\":15,\"pollenLevel\":\"H\",\"humidity\":80,\"windSpeed\":18,\"weatherCode\":7,\"uvIndex\":4,\"pollenType\":\"Grass\"},\"1499688000\":{\"precipitation\":23,\"maxTemp\":18,\"minTemp\":14,\"pollenLevel\":\"M\",\"humidity\":69,\"windSpeed\":11,\"weatherCode\":3,\"uvIndex\":7,\"pollenType\":\"Grass\"}}}"

Images

http://www.claritynallergy.co.uk/static/media/images/claritynallergy/7-trans.png&#8221; : 


I found Benadryl has one.

https://www.benadryl.co.uk/social-pollen-count


GET https://socialpollencount.co.uk/api/forecast?location=%5BLAT,LON]

Response

{"status_code":"200 OK","date":"2017-07-02T07:13:47+00:00","forecast":[{"date":"2017-06-29T08:00:01+00:00","pollen_count":"Low"},{"date":"2017-06-30T08:00:01+00:00","pollen_count":"Low"},{"date":"2017-07-01T08:00:01+00:00","pollen_count":"High"},{"date":"2017-07-02T08:00:01+00:00","pollen_count":"High","temperature":"18","weather_code":"01","weather":"Sunny"},{"date":"2017-07-03T08:00:01+00:00","pollen_count":"High","temperature":"18","weather_code":"07","weather":"Medium-level cloud"},{"date":"2017-07-04T08:00:01+00:00","pollen_count":"Moderate","temperature":"14","weather_code":"12","weather":"Light rain"}]}

Images

https://socialpollencount.co.uk/images/content/weather/07.pnp&#8221; :


App: https://itunes.apple.com/gb/app/benadryl-social-pollen-count/id638068252?mt=8

App doesn’t exist.


Progress
I’ve started building my own

img_4314 img_4315-1 img_4317-1
The Widget needs a lot of work but the basis is there, I’ve built a framework that gets all the data. Now to finish the UI…

Carousel View

iCarousel

I wanted to add an animation when dismissing, a button at the top and bottom of the view, one to dismiss, one to save, and move off in that direction.

MDCSwipeToChoose

TinderSimpleSwipeCards

@clsource added other directions

Directions

Jam Jar Cinema Wallet Passes

My local cinema is Awesome!

I want to create passes to keep a memento of the films I’ve seen. I order online so don’t get ticket stubs from the venue and I like having a digital copy, like CineWorld does.

 

There are a number of websites which allow you to make Wallet Passes.

I’ve recently tried PassSlot (https://www.passslot.com).

PassSlot

It has a free tier which allows you to create 1 PassID, multiple templates, and a set limit of passes, which is all I need.

It has an SDK which is great.

I created my Template with variables for the various pieces of information and now I have an iOS app which allows me to fill in the values, pick an image and create a pass.

It uses the iTunes Artwork Finder from Ben Dodson.

Wallet


The PassSlot API is available on ‘mashape’

The documentation mentions

Other Platforms – The PassSlot API is also available through mashape. They have client libraries for Node, Ruby, Java, .NET, Windows 8

On the marketplace

https://market.mashape.com/passslot/passbook

There is a button for open in Paw. I can’t get it to work at the moment.


I’d started making a Mac app to create Wallet Passes.

I followed the RW tutorials on PassKit but my PHP was rusty so never got that side working.

I got the local one working which used the sign tool and created all the files

  • pass.json
  • manifest.json
  • .pkpass
  • etc

JJC Passes (Mac) (1)

But when I tried to add them to my phone I ran into issues, I raised a bug will Apple and they are working on something.

The pass has to be served over SSL.

I made my own Contact Card: https://alexhedley.wordpress.com/2014/12/29/passbook/

Advertisements