PencilKit clearing canvas not always working - ios

I am building a PencilKit app that interprets a canvasView.drawing's size. Drawings below a certain size are interpreted as tap gestures and get cleared in the interpretation process.
Effectively, I am doing it like this:
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
// Check if drawing is empty,
// otherwise this would loop
guard !canvasView.drawing.bounds.isEmpty
else {
return
}
if canvasView.drawing.bounds.width < 10 &&
canvasView.drawing.bounds.height < 10
{
canvasView.drawing = PKDrawing()
handleDetectedTapGesture()
}
}
On my 2020 iPad Pro, this works flawlessly. On other iPads however, I observe a strange behaviour:
In a series of drawing little specks on the canvas that are all supposed to be cleared immediately, sometimes the canvas seems to not be cleared, a single speck stays visible. After I draw the next speck somewhere else, the clearing is functional again, which means the canvas was internally emptied, the visible state was just not up-to-date.
Finger input on the canvas is deactivated. The canvas tool is set to pencil, width 5.0.
Does anybody have an idea what could be the reason for this behaviour?

Related

WKWebView crashes at 30M of RAM usage on iOS 9

I have a WKWebView that loads a custom HTML file from our server. In our app there's a button to change the web page's font size using JavaScript by iterating through all elements and set their style property(this should be irrelevant since on other iOS it works perfectly).
On iOS 9 devices, when the font gets larger and larger, the webview gets progressively slower to respond to the font change. For example, changing from 22px to 24px takes 2s to take effect, and changing from 24px to 26px can take 3s or more. Eventually, when the font size gets to 28px, the webview would crash the app with a memory warning in the console. If not connect to Xcode, however, it would not crash but turn into a blank screen as described in this similar post.
This is not a duplicate since I'm asking for something different:
I have implemented webViewWebContentProcessDidTerminate and can confirm it gets called, but when I try to reload the webView it simply crashes again and fall into a crash-reload-crash loop. The Xcode panel shows my memory is using 31M of RAM, which like 5% for my iPhone 4S, so this shouldn't be a true memory issue. The web page consists of paragraphs of texts only, so is this a system bug or something that I'm doing wrong? Please comment if you need more details.
Here's my code:
class ReaderController: UIViewController {
// loads webView, injects JavaScript, handles button, etc.
func loadData() {
let html = // get html
webView.loadHTMLString(html, baseURL: htmlURL)
}
}
extension ReaderController: WKNavigationDelegate {
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
loadData()
}
}

moving app to background, calls viewDidLayoutSubView and create a lot of warnings with UICollectionView

it's all start from a lot of warnings about the width of collectionView cells,
That was written to console every time I press home button.
I thought it's something with size of the cells and tried to fix it.
Only after some testing, I notice that viewDidLayoutView is called with wrong view.bounds, and that make the collectionView cell bigger(in width) than collection view.
For now, my fix is to check if app is on background state and ignore viewDidLayoutView.
why it's happen only in iPad and not on iPhone ?
it's whirred that only now I saw this happening. it's something new in iOS ?
what is the right way to handle this ? I don't use auto-layout
its calling with wrong bounds and I don't want to calculate all cells frames just for the user to return to the same orientation.
I feel like I'm missing something very basic here OR there is some change on iOS that I'm not aware.
why it's happen only in iPad and not on iPhone ?
Because when you click Home on an iPad and the app goes into the background, the runtime takes two snapshots, one in each orientation, to use in the App Switcher interface (and in preparation for when the app comes back to the front). That means it has to rotate the app, which triggers layout, and so your viewDidLayoutSubviews is called.
it's whirred that only now I saw this happening. it's something new in iOS ?
what is the right way to handle this ? I don't use auto-layout
its calling with wrong bounds and I don't want to calculate all cells frames just for the user to return to the same orientation.
I feed like I'm missing something very basic here OR there is some change on iOS that I'm not aware.
Well, iPads have been behaving like this for quite a long time. It isn't my job to explain why you haven't noticed. Basically you should not be doing anything time-consuming in viewDidLayoutSubviews.
for now, my fix is to check if app is on background state and ignore viewDidLayoutView
That's perfectly reasonable. I do the same sort of thing. For example (this is a different method, but it's the same idea):
override func viewWillTransition(to size: CGSize, with tc: UIViewControllerTransitionCoordinator) {
if UIApplication.shared.applicationState == .background {
return
}
// ...
}
Be warned, however, that if you are doing manual layout and you don't do it when the app when goes into the background, your App Switcher snapshots may look wrong. Also, the fact that you are not using autolayout is a red flag. You should probably use it.

IOS iphone 4s not repainting dynamic images that are initially outside the viewport

I have been suffering from a bug for sometime:
I am doing something like the following:
$container.on('touchmove', function(){
$container.trigger( 'lazyload.appear');
});
$img.one( 'lazyload.appear', function(){
var that= this;
var $self= $(that);
$self.css('background-image', "url('real.path.to.img')" );
});
However, on IOS there seems to be a problem with repainting the background-images, when they are initially outside the viewport. When I drag my finger, until the image is in the viewport, the images aren't painted onto the screen unless i release my finger. I'm trying to aim for real-time, so I would like the image to be revealed as soon as I do a touchmove, but its being revealed at touchend when its initially outside the viewport. However, the console.log outputs that the background-image has changed before releasing my finger. When the image is inside the viewport, the repainting is fine, it repaints instantly as I drag my finger.
This seems to be a bug, or am I missing something? Thank you for your help!

How to design an iPhone app that uses both Portrait and Landscape in Flash CS6

So I have created an App that has a different menu when it is held portrait, but changes when held landscape.
I can get the navigation to work, However I am unsure how to design landscape pages inside Flash?
My stage is set to the standard 640x960 air for iOS, which gives me perfect portrait pages, But when I tilt my phone to landscape the screen obviously changes, and it looks weird. Im hoping someone can tell me how i can get this view inside Flash, while still having the portrait screens too?
I want to have both Portrait and Landscape in the same app, and am currently so confused how I can design this inside flash?
I hope this makes sense, and that someone could throw some help my way!
It's not easy, but you can do it. First, you have to wait until stage is initialized and set it's scaling property to no scale (this will stop resizing page to fill screen). Then you have to listen to stage's resizing (it trigger's every time you rotate iPhone) and to move/scale your display objects in proper way in the listener handler.
addEventListener(Event.ADDED_TO_STAGE, init); //Wait for stage initialization
private function init(e:Event):void { //init handler
removeEventListener(Event.ADDED_TO_STAGE, init); //remove listener, which won't be used more
stage.scaleMode = StageScaleMode.NO_SCALE; //set null scaling and top-left align
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, resize); //add handler for resizing
}
private function resize(e:Event):void { //triggers every time iPhone being rotated
//Move/scale your objects here
}

iPad parallax flickering

I am using a parallax effect with javascript but I'm having issues with iPad.
I know the "$(window).scroll" is not triggered on webkit touch devides - only when we release the screen - so i'm using:
window.addEventListener("touchmove", triggerScroll, false);
function triggerScroll(event)
{
var scrollTop = $(window).scrollTop();//event.touches[0].pageY; //window.pageYOffset();
$("#allCanvas .divCanvas").each(function(index, element) {
var speed = $(element).data('speed');
var initialTop = $(element).data('initialtop');
$(element).css('top', initialTop-(scrollTop*speed));
});
}
The problem is that it flickers the .divCancas a few pixels to the top or bottom depending if I'm scrolling to top or down.
I tracked the TOP value passed on $(element).css('top', initialTop-(scrollTop*speed)); and it's every time correct. The correct "TOP" value, eventhough webkit move it for a few milleseconds to the wrong position.
I tried also:
-"margin-top" rather than "top" with no difference.
-Removing all other objects and making the ".each" loop through only one div, so I guess is not a jQuery performance issue.
Has anyone came across this problem?
Many thanks
Diego
Maybe try using some of the -webkit css animation features... these run very smoothly on iOS devices. Here's a great demo of that (webkit only): http://jibjub.com/demo/HTML5/cube.html

Resources