ios

Yoink for iOS Icon

It’s here.
After an unnecessarily long, extended time in App Review, I’m so happy to be able to tell you that Yoink for iPad and iPhone with iOS 11 is now finally available on the App Store.

What’s Yoink for iPad and iPhone?

Yoink strives to improve and simplify drag and drop and speed up your workflow.
It accepts almost anything you can drag, copy or share on your iPad and stores it for later use. This way, your fingers are free for more important things.

Here’s a quick YouTube video of how it works (check your sound, there’s some music) :

How can I add stuff to Yoink?

Obviously, especially on iPad, Yoink was designed for drag’n’drop use, and using it as a Slide-Over or Side-by-Side app, I’d say that’s the best way to use it. Just slide Yoink over any app you’re in and drag to it anything you need later. Then slide it back out, if it’s in your way.
There are, however, other ways to add items to Yoink. It can grab the contents from your clipboard and it offers a Action / Share extension, so that whenever you use a Share sheet in iOS, you can add that shared item to Yoink – no drag and drop required. The app doesn’t even have to run.

How do I get stuff out of Yoink?

That’s just as easy. Either use drag and drop, or copy the items, or share them from within the app.
Yoink comes with a custom keyboard extension, which lets you use items you’ve stored in Yoink without having to leave the active app you’re currently editing text in – just switch to Yoink’s keyboard and drag out (or copy, if you’re on iPhone) the items to the destination in your text.
All items in Yoink are indexed by Spotlight, so you can use the system-wide search to find items. The results are draggable as well.

Yoink Custom Keyboard

How are items in Yoink represented?

Yoink creates a rich preview for every item you add, so that, at a glance, easy identification is possible (for example, web link items show part of the website, map locations show a preview using Apple Maps).
A full look at the item is available by tapping onto the item.

Deleting Items

Yoink doesn’t delete items right away. Instead, like in Photos.app, items you drag out of Yoink or delete are put into the Trash, where they remain for a specified amount of time, after which they’re really deleted.
So should you find you still need an item, you can restore it right away.

Pricing and Availability

Yoink for iOS is available on the App Store right now, for the introductory price of $2.99 (€3,49) – it will rise in November.
An iPad or iPhone with iOS 11 is required.

Yoink is also available on the Mac, and for the occasion, its price has also been reduced for a limited time! 🙂

Links

Yoink for iPad and iPhone Website: https://eternalstorms.at/yoink/ios
Yoink for iOS Usage Tips: https://eternalstorms.at/yoink/ios/tips
Yoink for iPad and iPhone on the App Store: https://itunes.apple.com/app/id1260915283?mt=8
Yoink for iOS Press Kit: https://eternalstorms.at/press/Yoink-iPad-1-Press-Kit.zip

Yoink for Mac Website: https://eternalstorms.at/yoink/mac
Yoink for Mac Usage Tips: https://eternalstorms.at/yoink/mac/tips
Yoink on the Mac App Store: https://itunes.apple.com/app/id457622435?mt=12
Yoink for Mac Press Kit: https://eternalstorms.at/press/Yoink-3-Press-Kit.zip

Delay of Release

I had planned and was ready for releasing Yoink for iPad together with iOS 11, on September 19th, 2017. As you may know, that didn’t work out. The app was ready, I was set, but App Review wasn’t happy with the app and so I missed the date, while other, let’s say similar apps, were allowed in.
After a lot of discussion by mail and phone with the App Review team, and having to remove some things from the app, Yoink was finally approved yesterday.

Thank you for your patience, and I hope you enjoy the app 🙂 Please spread the word and if you have the time and like the app, please consider leaving a little review on the App Store – it would mean a lot to me!

Eternal Storms Software Logo

– – – Do you enjoy my blog and/or my software? – – –
Stay up-to-date on all things Eternal Storms Software and join my low-frequency newsletter (one mail a month at most).
Thank you 🙂

Read more

ESSSquareProgressIndicator animating

What Is ESSSquareProgressIndicator?

It’s an indeterminate progress indicator originally developed for the iOS game ZEN.

It uses Core Animation (specifically, CAShapeLayers) to do its job and it’s pretty straight forward.

CGPathRefs, CAShapeLayer

CAShapeLayer has two animatable properties – -strokeStart and -strokeEnd (with a minimum value of 0.0 – start of path – and 1.0 – end of path). Going beyond 1.0 or below 0.0 doesn’t work.

So when trying to animate those values along a rectangular path – which was the first thing I tried when creating this – you do get a nice animation, but it ends at the 0.0/1.0 (which is, basically, the same) mark. So you end up with something like this:

glitchy progress indicator animation

The goal, then, was to animate beyond 1.0. The solution I came to – I’m sure there are other ways – was to use a second CAShapeLayer that animated alongside the first for the last/first part of the animation.

For a square, the values of the CAShapeLayer’s -strokeStart and -strokeEnd are as follows (starting at the top left corner):

CAShapeLayer strokeStart strokeEnd values

The CGPath begins and ends in the top left corner because I drew the path that way (you could make it start in the lower left corner or in the middle of a side, it all depends on where you start the CGPath with CGPathMoveToPoint).

The progress indicator starts at the middle of the left line and reaches to the middle of the top line. These are the two CAShapeLayers at work. The left part is one shape layer, the top line is another. I’ll do this in pictures I drew in code so it’s simpler to understand (the lines represent where the layer animated to, the dots are the invisible rest of the square).

Animating

Animation Part 1We start at this position. The line to the left is layer2(strokeStart:0.875, strokeEnd:1.0), the line at the top is layer1(strokeStart:0.0, strokeEnd:0.125).

Animation Part 2The transition to this is the reason we need two layers as we can not animate one layer beyond the 1.0 value.
So we animate layer2 to (1.0, 1.0) and at the same time animate layer1 to (0.0, 0.25) which makes it look like one line moving.

Animation Part 3This next part is easy. We animate layer1 to (0.75, 1.0).

Animation Part 4Lastly, we animate with two layers again to get to the initial position so we can repeat the whole thing from there on.
We animate layer2 from (0.75, 1.0) to (0.875, 1.0) and layer1 from (0.0, 0.0) to (0.0, 0.125) at the same time, again making it look like one line moving.

The Source Code

The repository (a sample iOS app, but the class works the same on OS X) is available on Github.

It was developed for iOS 7.1 but should work on earlier systems, and has been tested on OS X Yosemite, but should work on earlier systems as well.

You just drop in an ordinary UIView or NSView and set its class to ESSSquareProgressIndicator. Done. You can then set the color and stroke width right within Interface Builder thanks to the fairly new Xcode macros IB_Designable and IBInspectable.

Open Source

I have some more source code available here (or directly on my github profile page) if you’re interested. If you have any questions or feedback regarding this progress indicator, please be sure to mail or tweet me 😉

Enjoy!

—-
My name is Matt, I’m the developer of Eternal Storms Software. If you’d like to comment, you can catch me on twitter here: [twitter-follow screen_name=’eternalstorms’ show_count=’yes’] or by eMail.

Read more

First Concept of ZENFirst concept of ZEN

After last week’s guest blog post by my cousin Sebastian about how he came up with the idea of the iOS game ZEN, the design and conception process behind it and the soundtrack, today it’s my turn to talk about putting it in code and making it all come to life.

The Premise

Like a lot of developers I know, I became intrigued with programming because of games. As a kid, I always wanted to develop games for a living, make the next Diablo. So of course I jumped at the idea of creating a game when my cousin asked me if I was interested.

I had never actually programmed a game before, so when Sebastian approached me about developing a game with him, I was already seeing myself having to learn OpenGL and everything that comes with it.

Luckily, it soon became clear that it would be a 2D game, almost 8-bit-ish, like an old Super Mario Bros game. So my fears of having to learn something new* were put to rest and the more he told me about the game, the more I realized that Core Animation would be the perfect fit for this project.

The game is about a cube with random numbers on it. Your goal is to reach ten with these numbers by turning the cube and selecting the appropriate sides within ten seconds.

ZEN Cube Animation

*just kidding, I love learning new stuff, but for a side-project having to learn OpenGL would have been a little much, especially with all my other apps that need constant attention

Core Animation actually was pretty much made for this kind of stuff. Even if the game had had some 3D effects (for example, some sort of perspective distortion when turning the cube, etc), it would have been fairly easy to implement.

First Blood

The first thing I did in the process of developing ZEN was to prototype the cube itself. I began by mapping out the cube because a) I didn’t have one handy and b) to get a visual on each side:

Mapping out the cube

Because I was using Core Animation and it was all in 2D space, I had to figure out what side would go where when the cube was turned from left to right, right to left, from the top or the bottom, so that the numbers would stay on the same side and not end up any place they shouldn’t be. I went so far to write down which side would go where once the cube was turned in any direction

Mapping out which cube side would go whereWhich side goes where when turning the cube?

To make the animation possible, I would have to use at least two CALayers that changed in shape and color, and would have to be kept up to date in terms of data (which side holds which number).

One layer would always be hidden, the layer to turn to, so to speak, the other layer would always be visible. They would alternate in doing that.
For example:

Layer 1 is visible with the front number of the cube.
You turn the cube right and layer 2 (still hidden) gets the number of the left side of the cube.
Layer 1 is animated to fold to the right
Layer 2 shows and animates to the full size of the front cube side.
Layer 1 is hidden

Turning Cube Down on PaperTurning the cube from the top on paper

With that done, I had the cube – of course, there were some kinks to be worked out (for example, sometimes the hidden layer would suddenly be visible with a completely wrong size), but basically, the cube was working.
In code, turning the cube upwards looks like this:

- (void)turnUp
{
ESSCubeSide *oldUp = self.topSide;
ESSCubeSide *oldFront = self.frontSide;
ESSCubeSide *oldDown = self.bottomSide;
ESSCubeSide *oldBack = self.backSide;
self._cubeDict[ESSCUBE_FRONT] = oldDown;
self._cubeDict[ESSCUBE_TOP] = oldFront;
self._cubeDict[ESSCUBE_BACK] = oldUp;
self._cubeDict[ESSCUBE_BOTTOM] = oldBack;
}

This is only the data model, of course. The view code just the two layers – resizing them in unison, hiding one layer and showing the other, etc.

Random Numbers

The next thing that had to be done was to fill the cube with random numbers, some of which would add up to ten.

I chose to do the following:

  1. Decide how many sides it takes to solve the current cube (a number between 2 and 6); let’s say it’s 3 – 3 sides to solve the cube.
  2. Loop while we create 3 random numbers between 1 and 9 that add up to ten.
  3. Fill the rest of the cube (3 more sides) with random numbers between 1 and 9.
  4. Shuffle the resulting array of six numbers so the solving sides aren’t always on the same sides
The same principle works for the minus mode, where there are positive and negative integers that you need to select to add up to ten.

Interface

The first interface concept, as you can see in the first screenshot of this blog post, was pretty simple. The title and three buttons. There was no mention of animations!

As it always happens, things change during the development process, you iterate on everything, and the interface gets overhauled as well. This new one was, in my opinion, much nicer as it demonstrates the “cube-y” nature of the game very nicely.

ZEN Line animation

But it took me some time to get there. I was hoping that Sebastian could define the animations in svg or gif or something like that and I could just load them in and display them.
However, I could not do that – apparently iOS doesn’t support svgs or gifs out of the box (and I didn’t want to rely on 3rd party libraries to do the job). After googling around for a couple of days (because, you know, you want to be thorough), I tried doing it in a web view, because these animations would work in the browser. However, I wouldn’t have that amount of control over them as I did with the final approach I took – code it in Core Animation as well.

So I have one view class that, depending on the width and height of the bounds of the view either expands horizontally or vertically. That was the easy part.

The hard part was creating all the views in Xcode’s Interface Builder with the proper dimensions and positioning them so they would define the buttons and letters. I’m just glad the Help – view is not animated 😉 :

Help ViewThe Help View – thankfully for me, not animated

Creating ZEN was a very exciting experience and I learned a lot during the process. As I usually work alone, working within a team on this project (even if it’s just two people) was a breath of fresh air and is a lot of fun, bouncing ideas off of each other, inspiring each other – there’s a whole lot of energy there.
While I do have a few dear friends with whom I can exchange ideas over the internet for my own projects, it’s quite different when you’re one on one, face to face.

It’s been  a lot of fun.

—-
My name is Matt, I’m the developer of Eternal Storms Software. If you’d like to comment, you can catch me on twitter here: [twitter-follow screen_name=’eternalstorms’ show_count=’yes’] or by eMail.

Read more