Nesting views deterioriates image quality - ios

I ran in to this problem on a recent project when the guys in the art department noticed deteriorating image quality. I'm not sure what's causing it however we were able to remedy the issue by removing the ScrollView it was nested in. But this is not a viable solution as we will need to nest images within views nested within scrollviews.
My code looked something like:
<View>
<ScrollView>
<View>
<ImageView image="someImage.png" />
</View>
</ScrollView>
</View>
When we removed the ImageView from both the nested ScrollView and it's direct parent view it renders fine. I've created a repo with a simple project illustrating this. The dulling effect is most noticeable on the coloring of the letters, the white drop shadow on the text and the blurring of the grey border.
https://bitbucket.org/bwellons/blurry-images
Is this a bug that needs reporting or is there documentation somewhere that says "don't do it this way" that I don't know of?
Regards
Brant

I think this is caused by not defining bounds (width, height) and anchors (top, left, right, bottom) of views in a consistent manner, for example, if I just change this:
".parent": {
width: '100%',
height : 59,
}
To this:
".parent": {
top : 0,
width: '100%',
height : 59
}
The blurring goes away. I think this is happening because you are mixing relative and absolute view layout techniques (percentages and absolute pixels) in a tightly bound box (the .parent view is the exact same height as the child image view) which is causing the layout calculations underneath to fudge a little when they draw the image inside the parent view.
I say this because this also works to noticeably eliminate the blur, by allowing more room for transformation error:
".parent": {
width: '100%',
height : 62 // Added 3 pixels of padding
}
Here are some other methods that work as well, by either using the same layout mechanism for both width and height, or giving more room for transforms:
".parent": {
width: '100%',
height : '50%' // Dont do this, but shows the point
}
".parent": {
bottom : 0,
width: Ti.UI.FILL, // I use Ti.UI.FILL instead of 100% generally
height : 59
}
So generally, stay away from mixing percentages and absolute values in nesting view chains dimensions, unless you are willing to give some wiggle room in the parent, or define anchors (top, left, right, bottom) to make the drawing transformations work out.
Disclaimer: I only base this statement on about 15-20 different limited layout tests and my own experience (I did not go through native code, yet) so this is by no means science.

Related

SwiftUI - How to add padding outside border

In CSS there is padding and margin, the former adds empty spaces inside border, and the latter adds spaces outside. Currently I am learning SwiftUI, and I found the .padding modifier, which is equivalent to CSS's padding property, but cannot find margin's correspondence.
Does it exist or am I to create a wrapper view to achieve this goal?
SwiftUI's layout modifiers can be a bit confusing if you're coming from HTML and CSS.
Where CSS has a huge list of properties to choose from, SwiftUI tries to keep things simpler. To do that, it takes advantage of the ability to "chain" modifiers together.
For example, if you had a rectangle that needs internal padding of 8 pixels, a border of 1 pixel width and external margins of 10 pixels, you might express it in CSS like this:
.my-rectangle {
padding: 8px;
margin: 10px;
border: 1px solid red;
}
And in CSS it doesn't matter what order those properties occur within the double braces; each has a specific meaning and is applied in the same way, even if the border property is at the end or the beginning.
In SwiftUI, though, styling is done by applying a modifier to a View, giving you a new view with the modification applied. You can then apply another modifier to that, and another, and so on. And because each modifier is adapting what has gone before, the order is very important.
So if we have a view to which we need to add the same spacing as the example above, we'd structure it something like:
MyView()
.padding(8) // <-- internal padding
.border(Color.red, width: 1) <<-- apply the border
.padding(10) // <-- apply more padding outside the border
Building views up gradually like this is what allows SwiftUI to keep the number of modifiers you need for most views reasonably small and focussed.
As you start building up more complicated views, you'll come across stacks and grids, which also have a concept of spacing between children. Depending on your design, it might be more useful to think about using spacing instead of external padding, especially if you start breaking your design up into reusable components.
But thinking about applying changes in a sequence, instead of all at once like CSS, is the key to constructing great SwiftUI views.

Make an image in Kivy exactly the same size as the widget bounding box

I'm having trouble in Kivy setting an image size. I want to keep the aspect ratio fixed but I also want to position things precisely over the top of the image.
To do this, I make a RelativeLayout that has the same size and position as the image. However, when I check the size of the layout, it is always slightly larger than the displayed image. Making precise alignment very difficult. The wiki mentions something like this:
By default, the image is centered and fits inside the widget bounding box. If you don’t want that, you can set allow_stretch to True and keep_ratio to False.
They also include code if you want to make the image slightly larger than the containing widget:
<-FullImage>:
canvas:
Color:
rgb: (1, 1, 1)
Rectangle:
texture: self.texture
size: self.width + 20, self.height + 20
pos: self.x - 10, self.y - 10
But nothing about making them exactly the same size!? Surely I should be able to dictate the containing widgets size so the aspect ratio etc. is exactly as required.
I have tried many things but whatever I try, I cannot get the outside edges of the displayed image and a layout to coincide.
Does anyone have any experience with this?
Apologies, I have discovered the problem, the images had a transparent border that I wasn't aware of (the images were passed on to me from elsewhere) I have removed this and it has solved the problem.

set individual Area inside Map in MapKit

I am trying to set an individual Frame which defines the visible area of the Map.
Currently all the annotations are shown with mapView.showAnnotations but they aligned to fit in the whole iPad screen view. So they are partially hidden by Floating UI Elements (Green). Also the center of the screen is aligned to be the center of the iPad screen.
What I try to accomplish: I want something like a defined rectangle inside the Map to be the only regarded area in the map. But the Map itself (blue) shall still be shown behind the UI Elements.
I thought it would be able to accomplish this by using setVisibleMapRect but when I ever I try to use this it does not take any effect. Is setVisibleMapRectactually the needed method to solve this problem?
The actual answer I found out later is defining
mapView.layoutMargins = UIEdgeInsets(top: X, left: X, bottom: X, right: X)
so the map wont use the space defined by the margin
For others finding this via google, looking for a solution with MapKit JS:
In MapKit JS, the property to modify is called padding:
var map = new mapkit.Map("map");
// When showing the translucent side panel, shift the map content a little to the right.
if (window.innerWidth >= 768) {
map.padding = new mapkit.Padding({top: 0, left: 600, bottom: 0, right: 0})
}
Documentation: mapkit.Padding

Vertical or horizontal rule in Vaadin Flow

I want to section off one area of a layout from another visually in my Vaadin Flow layout using the Java API.
I want something like the hr horizontal rule found in HTML. I would also want the equivalent, a vertical rule (which was never defined in HTML).
Is there some easy way to have a visual indicator of a thematic shift between parts of a layout?
Hr class
For an <hr> there is the Hr class.
verticalLayout.add(new Span("First"), new Hr(), new Span("Second"));
Roll-your-own
Another option is to create classes for the dividers, there are a few different ways of doing this, here's an example
public class Divider extends Span {
public Divider() {
getStyle().set("background-color", "blue");
getStyle().set("flex", "0 0 2px");
getStyle().set("align-self", "stretch");
}
}
And used as such
horizontalLayout.add(new Span("First"), new Divider(), new Span("Second"));
Using align-self and flex will only work in flex layouts, which includes HorizontalLayout and VerticalLayout. The beauty of this approach is that the same class will work in both. The flex: 0 0 2px tells it to be 2 pixels wide in the direction of the container, and not grow or shrink. The align-self: stretch will tell it to take the full size of the container in the perpendicular direction.
I write this answer as follow-up to my comment on Tazavoo's answer, which is great! I love their custom Divider class, and it has been asked whether this divider can be customized/styled further, something like it is done in this gradient borders page.
Of course this divider can be styled further! But the difference between the divider and the elements in the link is that in the link, the borders of an element is styled, while we need to style the actual element itself here.
CSS attribute in the linked page: border-image. CSS attribute for the Divider background-image.
(I am not familiar enough with CSS -webkit attrributes, so I don't know if you need more than just background-image for a good visualisation in all browsers)
The linked page makes the linear-gradient go in the direction to bottom. We could use that too, but then using the Divider horizontally would look different than using it vertically. That is why we need to set the direction to a diagonal, so both usages of the divider have a similar gradient. See proof of concept in w3schools' TryIt Editor
Here is how I set up the Divider class with a gradient:
public class Divider extends Span {
public Divider(){
getStyle().set("background-image", "linear-gradient(135deg, #777 , rgba(0, 0, 0, 0))");
getStyle().set("flex", "0 0 2px");
getStyle().set("align-self", "stretch");
}
}
To customize the linear gradient even more, please see the docs on w3schools
All the credits of the divider class go to #Tazavoo. Please go upvote their answer

reduce empty space at the top of presentation

I'd really like to be able to decrease the amount of padding at the top of all my level 2 reveal.js slides (version 2.6.2). It doesn't appear to be possible to customise this with CSS because the offset is a negative number calculated dynamically.
e.g. in http://fommil.github.io/scalax14/#/5/1 I would like to reclaim at least 200 pixels at the top. The top parameter is currently being calculated to be -350px but I'd really rather it was closer to -500px.
Is there a way to do this with config?
Reveal keeps the aspect ratio of the resolution you entered in the config.
If you want your slides to have less padding, there are multiple ways:
disable centering:
center: true, // add this in init or config
slides get positioned at the top of the page, and all the padding happens at the bottom
use a 4:3 format for your slides
width: 1024, // add this in init or config
height: 768,
this will move all padding to sides of the page (well, assuming the browser window is not resized) as long as the page ratio is wider than 4:3
create fully responsive slides:
var resizeSlide = function() {
Reveal.configure({
width: window.innerWidth,
height: window.innerHeight
});
}
setInterval(resizeSlide, 1000);
you will then need to make your slides responsive to changes in slide format, but this will make them utilize the full page for the presentation.
I'm using setInterval and not onResize because onResize just don't work on mobile and some browser/os combination (i.e. chrome on windows 8.1 when using keyboard shortcut and desktop hotspots to resize the window)

Resources