Armagan Amcalar

Armagan Amcalar

Software architect, JS enthusiast, electronics engineer,
Apple fan, guitar geek and stuff.
Early to bed and early to rise, makes a dev happy, healthy and wise.
Comments

Google’s exact search is broken. It will parse “(?:button)input)$” however it wishes, and incorporate meaningless results.

I don’t know for how long this was the case but it’s quite useless.

Comments
Is the real art of living to overcome our wounds, make the best of our limitations and embrace our gifts?
- Perception – S03E03
Comments
But how could we trust our own belief systems when our brains are giving them emotional kickbacks? By balancing it all with critical thinking, by questioning everything and by always, always being open to the possibilities.
- Perception – S02E13
Comments

WWDC ‘14 Keynote – Swift and iOS Development

image 

The keynote is just over. I was so overwhelmed by the new gems in OS X Yosemite, the new developer APIs and services just took my breath away.

The biggest take-away was Swift, a new language Apple put in place of Objective-C which was the de facto standard of native applications up until now.

A few months ago I predicted that Apple would quit Objective-C this year. It was so obvious, in 2014, using a language and idioms from 30 years ago. But I thought the shift would be towards JavaScript, which is the de facto standard of the web.

Why JavaScript? Because it’s an awesome dynamic language with all the features developers hailed for today in Swift (for years, at that).

Why JavaScript? Because Apple has most of Cocoa Touch already in JavaScript since 2008; lastly with iAd Producer.

Why JavaScript? Because a single code-base for all your needs.

Why JavaScript? Because Apple just announced a new JavaScript processing engine for WebKit, which nearly brings JavaScript up to native speed.

All the stones were in place for this year for a switch over to JavaScript and I’m very disheartened by it not happening. Now there’s a new cool IDE for Swift and the engineering team has all the iOS APIs in place for Swift with all the documentation. What a great engineering effort. By now, Apple has the same APIs in Objective-C, JavaScript and Swift. :)

Yet again, I’m enlightened to finally see Objective-C fade away. I hope that Swift will be a great welcome after all these years of Objective-C. I’ve already begun thinking on a transpiler from Swift to JavaScript and vice versa :)

Update: Here’s the link to the extensive book about Swift. It looks so much like a mishmash of Go and ES6, I only wish the effort was spent on the latter.

Comments

Chris Leon demonstrates a very nice video where he plays his own implementation of a delay pedal with pedalboard.js, the first and best open source library for developing guitar pedals with HTML5 Web Audio.

Thanks to Chris for his great work!

Comments

If Flipboard is Edison, Zite is Tesla.

Today I read that Zite is being acquired by Flipboard.

For the past two years, Zite has been an integral part of my life as I use it at least for half an hour every single day. It’s been a great resource of, well, resources for development. I’ve even been featured once with pedalboard.js.

But all good things must come to an end, I guess. I am a big Zite fan, I even built a web-based interface for Zite to read while I’m not on mobile.

I can’t believe how people think Zite is like Flipboard; it’s far more superior in every aspect. If Flipboard is Edison, Zite is Tesla. Yeah, I liked that analogy.

I’m really worried for the acquisition, as I know nothing good ever comes out of one. I’m glad that, apparently, Mike Klaas is joining Flipboard, but hey; I really dislike Flipboard. It’s a piece of crap compared to Zite, and I find it shameful for such a great product (Zite) being acquired by a such a pompous product (Flipboard). But that’s how marketing goes, I guess.

I will use Zite for the rest of its lifetime, and hope to find all its greatest features in Flipboard. Maybe then I can like it.

Comments

Acik kaynak

Anonim turkuler acik kaynak dunyasinin en guzel ornekleridir. Bilginin, kulturun, kalitenin paylastikca arttiginin gostergesi; sahipligin, tekelin, mulkun temelsiz ve basarisiz oldugunun kanitidir.

Acik kaynakli seyler yuzlerce yil yasar, el degistirir, buyur ve herkes kendinden bir seyler katarak yogurur. Basarisinin ve kaliciliginin sebebi budur.

Ticari kaygilarla; ustunluk kurmak, guc elde etmek icin yapilan girisimler eninde sonunda batmaya, unutulmaya mahkumdur.

Comments

Epic CG and script writing.

Comments

Introducing the baking soda paste technique for fixing rubber-band scrolling on iOS

Baking soda paste is one of the best practices when it comes to dealing with rubber stains or, well, rubber-band scrolling on iOS. This is an in-depth guide to defeat the bad habits of iOS and let your web app vibe more like a native app.

Before we begin, you might want to check out a simple example with the baking soda paste technique in the works, or a more complex example with an app-like layout. Make sure you open the examples in your iOS device.

Introduction

This little technique lets you deal with the disgusting rubber-band scrolling on iOS devices. With Baking Soda Paste technique, web applications look more like applications than web sites. As an added bonus, the technique hides the address bar in iOS 6, leaving the precious space for the app. A third fix is for web apps in iPhone 5. Due to unknown reasons, by default they appear with black bars on top and bottom.

So, baking soda paste solves 3 problems;

  1. Rubber-band scrolling in iOS Safari.
  2. Hiding address bar.
  3. Black bars in full screen web apps.

Another nifty bonus is inertial scroll everywhere. You know, Safari’s scrolling is not like its counterpart in native apps. It’s made for improving reading experience, some claim. But I find it restrictive. With baking soda paste technique, you get inertial scroll in your web apps for free, without going on a limb and type-webkit-overflow-scrolling: touch on everything.

Ingredients

Check out the repo on GitHub and;

Explore simple.html for fixing rubber-band scrolling in basic terms. This is as simple as it gets. With a few CSS rules, you can prevent rubber-band scrolling on overflowing elements. It doesn’t apply to non-overflowing elements, though.

Explore complex.html for the full technique, including all three fixes. You can mix and match any as you like. It includes a header and a footer along with a content area, as seen in many applications.

Explore complex-annotated.html for detailed inline explanation for the full solution. It helps with understanding quirks.

How to apply

Everybody has a different style when it comes to constructing a web app. Therefore, this technique is as sparse as possible and can be applied in parts to your solution. Just take the simple solution to rubber-banding, or mix and match parts from the annotated source.

Breakdown

The beginnings of a web app

The default browser width is 980px in Safari in iPhone. This is to show whole desktop pages in a very tiny fashion, albeit complete, in that screen. It’s also zoomable by pinching.

A native app uses the actual device pixels, so should we. And there’s no zoom so we should fix that too. In order to achieve this, use the following meta tag.

Now actually, initial-scale=1 makes sure there’s no initial zoom, user-scalable=no makes sure a user cannot zoom in or out, and width=device-width makes sure we use the actual device pixels.

Well, almost. The retina iPhone has 640 pixels in horizontal but this meta tag makes the browser think it has 320 pixels. So you just can’t use 1-pixel-wide design elements. The 1px in your CSS will amount to 2 pixels on screen.

If this is a problem for you (it mostly will be), you can just use a scale value of 0.5 as in:

This makes sure that we really use the whole device pixels, and you can make your designers happy once again by letting them use 1-px-wide elements.

Rubber-banding

It all began with the disgusting rubber-banding effect. Well the effect is not so disgusting, it’s rather cool in fact (with things like pull-to-refresh, etc.), but you just don’t want it in your web app.

We’ll begin with the rubber-banding effect that are triggered by scrolling past limits in scrolling elements. You know, the ones that have a lot of contents inside. You scroll to the top, and want to scroll further (like when you want to see a pull-to-refresh icon). And when you expect a native app to just scroll the contents, you’re pulling the whole viewport! Now that’s very bad, but it’s actually very easy to prevent rubber-banding in scrolling overflowing elements. An overflowing element is one whose height is smaller than its contents’. It may or may not be scrolling; and although an element doesn’t have any scrollbars, it can be an overflowing element.

For example, inline elements take the dimensions of their surroundings. But a block element in an inline element may be bigger than its container. By default, browsers will display the content fully, but the outer inline element is already overflowing, like with the overflow: visible CSS rule. The same idea may be found in hieararchical block elements; when the inner element goes out of its container, it means the container is overflowing. You can scroll it if you apply overflow: scroll.

So, putting the non-scrolling overflowing elements aside for now, the scrolling elements are easily fixed.

You just apply the following rules to html and body tags:

html, body {
    height: 100%;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}

And these to your scrolling element as in:

#content {
    height: 100%;
    overflow: scroll;
}

Really simple, right? You must have seen other nasty solutions that even try to scroll the element 1px off when you reach an end.

So open up simple.html in your iOS Safari while you enjoy a goodbye toast to rubber-banding. Now let’s step back for a moment and try to understand what’s going on here.

First, you set the height property to 100% for the body and the html. These assure that the body will fill the screen and will not scroll past beyond it. And any overflowing content will be scrolling inside the body.-webkit-overflow-scrolling is another key factor and serves a double purpose. One, it enables inertial scroll on every element and two, it just provides the rubber-banding fix.

Make sure to have a finite height on the content container as in the example, and just applyoverflow-y: scroll. Magic.

Now don’t get me wrong, I have definitely no idea why this works. But it really does.

And how about non-scrolling, non-overflowing elements? Well they are a bit more tricky and cannot be dealth with CSS only, therefore they require JavaScript. But more on that later.

Complex example application layout

The other fixes are demonstrated in the complex example. The example features a header, a content area and a footer as found in many applications, and are fit for such layouts. You can work the fixes out for other layouts as well.

This app layout features a 60px header, a flexible-height content area and a 60px footer.

Hiding the address bar in iOS 6

The address bar in iOS 6 is actually more friendly to developers than its cousin in iOS 7. Although iOS 6 is waning in market share, it’s still out there along with 3:2 iPhone screens. So that leaves a really small canvas for our apps and that’s irritating. So let’s get rid of it!

Now the first thing is, we have to make sure that we’re in iOS 6 and actually in a browser (and not in standalone mode where the user added the application to home screen via the Add to Home Screen button), since iOS 7 doesn’t let you hide the address bar and in standalone mode there’s no browser chrome.

Here’s a very crude and simple OS version sniffer;

if (navigator.userAgent.indexOf('iPhone OS 6') > -1) {
    document.body.classList.add('ios6');
}

If the user is using a version of iOS 6, we just add a class called ios6 to the body.

For detecting the standalone status, we use:

var standaloneClass = navigator.standalone ? 'standalone' : 'no-standalone';
document.body.classList.add(standaloneClass);

Now we have the actual state in CSS. For hiding the address bar, the body should be 60px longer than the full viewport in iOS6 Safari. But we had used 100% for body height previously! Don’t panic. Just use this:

body.ios6.no-standalone {
    padding-bottom: 60px;
}

This gives a 60px space at the bottom. Now if the user would scroll down, the address bar would disappear. But we want it to happen automatically as soon as the app loads!

So here’s a pretty one-liner to append to anywhere you like.

document.body.scrollIntoView();

Very cool, huh? Well, that additional 60px looks really bad. We have to cover up for it!

Now assuming you have a footer at the absolute (position: absolute) bottom (bottom: 0;), you can do this:

.ios6.no-standalone footer {
    bottom: -60px;
}

That’s more like it. Now there’s a gap between the content and the footer! Never mind, just push the content further down:

.ios6.no-standalone #content {
    bottom: 0;
}

That does it. We hid the address bar!

Standalone mode

Standalone mode is when a user adds your page to the home screen. It’s possible to hide the browser chrome there, so that would feel a lot more like a native app. First of all, you need to add the following in order to be able to hide Safari chrome in apps added to the home screen. This enables the standalone mode.

It comes with a few problems, though. First, the status bar is pitch black in iOS 7. Second, there are strange bars on top and bottom, as if you opened an old iOS app that doesn’t support 4-inch displays in a 4-inch device. Weird. To get rid of the bars, we have to add a second meta tag.

This tag is only valid for 4-inch devices. The strange thing is, you have to remove width=device-width this time!

Now, for the status bar. For consistency between iOS 6 and 7, we prefer to have a black-translucent status bar in standalone mode:

Having any value other than default fixes the black status bar issue, but again, for consistency, let’s stick with black-translucent.

It lets you use the whole display as a canvas, just like in iOS 7. So your actual content goes beneath the status bar and is visible there. For that reason, we need to leave a space for the status bar. Since its height is 20px, we just make the header taller and push the content further down.

.standalone header {
    padding-top: 20px;
    height: 80px;
}

.standalone #content {
    top: 80px;
}

Great!

Rubber-band scrolling on non-scrolling elements

Now, if you want to scroll in a scrolling element, there is no rubber-banding. But you can actually pull down the viewport if you start dragging on a non-scrolling element (like the header or the footer).

Now that’s also an imperfection we don’t want in our app. So we need to resort to JavaScript for preventing touch moves that happen in those elements. We’ll begin by listening touchstart events on the body. Whenever a touchstart occurs, we’ll immediately listen for a touchmove event to see if we need to prevent it. Just one touchmove event is enough to determine this, so we’ll unlisten the consequent touchmoves for performance reasons.

Now that we have a touchmove event on an element, we need to see if its as tall as its contents, or shorter. If the element is shorter than its contents, it means it should be scrolling, so we shouldn’t prevent the event. Keep in mind that our backs are safe with the previous simple solution, i.e., there won’t be a rubber-banding effect on scrolling elements.

But if it’s not shorter, than we should prevent the touchmove event so that it won’t trigger rubber-banding!

Keeping in mind that the DOM is a tree and there can be a lot of elements up that tree starting from the element we caught the event on, we need to traverse up the tree – up to body in fact (since we know that it shouldn’t scroll).

That’s about the whole story. Here’s the code.

document.body.addEventListener('touchstart', function() {
    document.body.addEventListener('touchmove', function moveListener(e) {
        document.body.removeEventListener('touchmove', moveListener);

        var el = e.target;

        do {
            if (parseInt(window.getComputedStyle(el, null).height, 10) < el.scrollHeight)
                return;
        } while (el != document.body && el.parentElement != document.body && (el = el.parentElement));

        e.preventDefault();
    });
});

There’s one problem with this approach, though. Sometimes you are just not careful enough, and you have some elements who are shorter than their contents but shouldn’t scroll, e.g. elements that act like they haveoverflow: visible. Now you can check against those elements in the code above, but I discourage it as it will have a performance impact. Plus, it prevents you from being cautious when writing CSS. Just write correct CSS; a container should, almost always, be at least as tall as its children.

Another feature of this approach – I recognize some might say it’s a problem – is that it completely disables the address bar. So the user cannot scroll it back down, either to refresh the site or change the URL to navigate away. Or, use the search box for searching for something in your app.

You can enable the address bar by letting the do-while loop reach the body, i.e., by removing the bodychecks in the while condition. I just have no use for the address bar in an app, so I prefer it this way.

Conclusion

So, that’s all about it! With the Baking Soda Paste, you don’t have to fear the rubber-banding ever again! Apply it thoroughly, rinse and repeat, and don’t forget to ping me back if you like it!

Wait! What about Android?

Sorry, I have little experience in the vast realm of browser quirks in Android. Some of the tricks here work for Android too, but I don’t have any device or the will to make it work for all Android devices. But your contributions are welcome!

OK, a quick tip about Android though.

If you want to go retina and resort to using 0.5 for initial-scale property, most Android environments will just show the app on a quarter of the screen. In those cases, just add a spoonful of target-densityDpi=320 to the meta tag and the problem will be solved. iOS ignores target-densityDpi setting, so you can just leave it there.

Comments