What's the best way to reorganize elements in a view after rotation? - objective-c

I have a subview with (in addition to other standard Cocoa Touch controls) 6 buttons and labels inside of it.
I'm rotating & resizing these buttons and labels on the rotation event with this messy code.
- (void) updateLayoutForNewOrientation: (UIInterfaceOrientation) orientation {
if (UIInterfaceOrientationIsPortrait(orientation)) {
button1.frame = CGRectMake(20, 59, 130, 80);
button2.frame = CGRectMake(170, 59, 130, 80);
button3.frame = CGRectMake(20, 176, 130, 80);
button4.frame = CGRectMake(170, 176, 130, 80);
button5.frame = CGRectMake(20, 293, 130, 80);
button6.frame = CGRectMake(170, 293, 130, 80);
label1.frame = CGRectMake(20, 147, 130, 21);
label2.frame = CGRectMake(170, 147, 130, 21);
label3.frame = CGRectMake(20, 264, 130, 21);
label4.frame = CGRectMake(170, 264, 130, 21);
label5.frame = CGRectMake(20, 381, 130, 21);
label6.frame = CGRectMake(170, 381, 130, 21);
} else {
button1.frame = CGRectMake(20, 59, 130, 60);
button2.frame = CGRectMake(20, 155, 130, 60);
button3.frame = CGRectMake(177, 59, 130, 60);
button4.frame = CGRectMake(177, 155, 130, 60);
button5.frame = CGRectMake(328, 59, 130, 60);
button6.frame = CGRectMake(328, 155, 130, 60);
label1.frame = CGRectMake(20, 127, 130, 21);
label2.frame = CGRectMake(20, 223, 130, 21);
label3.frame = CGRectMake(177, 127, 130, 21);
label4.frame = CGRectMake(177, 223, 130, 21);
label5.frame = CGRectMake(328, 127, 130, 21);
label6.frame = CGRectMake(328, 223, 130, 21);
}
}
That's a bit messy, but works fine and I have a precise control of element position in the view.
By the way I'm wondering if having two different views and flipping them on rotation is more efficient regarding "cpu power" and memory consumption (I think that having a single view instead of two is better for memory, but I could be wrong, I'm pretty new to ios programming).
Thanks for any suggestion!

Right now I am working on a similar code what you wrote. The project it is very big, hard to follow what where to modify. It was written for iOS 3 and now the client needed a few modification. It wouldn't so big the problem, if the iOS wouldn't change the pushModal and would be deprecated in iOS6... In my case needed to rewrite the GUI skeleton, and I had Portait / Landscape requirements. Check a few links if you would like it: question1
question2 question3 question4
For a not previsible iOS change it will be to hard to overview that code, especially after 2 year. I wouldn't repeat that programmer mistake who has worked before.
In your case that is my I would choose from different solutions ( but this for sure not) :
Solution 1: Create different xib for landscape and portait.
Has the advantage of the modularity: later if you don't need Landscape for various reason it is easy to unlink from your code. Has the disadvantage of creating a new view ( well it can be cached) but still different objects and need synchronizations of data, between model-View2-controller.
Solution2: use only 1 xib file and layout automatically the components by setting up they properties at size inspector ( 5th tab ). Very hard to configure
Solution3: inside that xib file create component-landscape and layout those components to mach the expected design, size, and at Runtime read they size and set it, as you so now, but that can be edited visually.
Storyboard or xib, it is almost the same for me, there can be 2 UIViewController and pop / push the Portait/Landscape to not fill the stack with rotations :)
Speed ofc it is the best if you don't rotate at all, but if you still want, maybe the 2 component in 1 xib, because not need to change the visibility 2-4 times, wich will trigger a lot od function calls: viewwillappear, wiewdidapear, viewwilldisapers and so on.

You ask:
By the way I'm wondering if having two different views and flipping them on rotation is more efficient regarding "cpu power" and memory consumption ...
I believe that the opposite is true. It's far more efficient to have a single view for which you simply invoke your method from viewWillLayoutSubviews (in iOS 5, in iOS 4 I generally use willAnimateRotationToInterfaceOrientation). The efficiency gain is modest, but if efficiency is your goal, I think a single view is the way to go. You might want to use the separate views if they're radically different and thus your code would become hard to manage with a single view, but otherwise I stick with one view. Personally, I also think it's a stronger user interface to have the controls animate into place as you rotate the device.
Personally, when I have content that reorganizes on orientation changes like this, I try to refrain from using hard coded coordinates, but rather use the dimensions of the view to algorithmically determine the the layout of my controls (e.g. how many per row) and from there, determine their coordinates. This way, it takes care of not only landscape versus portrait, but also makes Universal apps (especially if there's ever other devices with different screen sizes in the future) easier, too. I think we can also look forward to iOS 6 also offering some nice enhancements to laying out controls (though it will be a while before we will feel comfortable developing apps that require iOS 6).

Related

How can I convert Bytes Array to String on Kotlin other than String()?

[51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119]
This is the BytesArray that I want to print in String.
When I searched on the internet, I found that
String(Bytes, Charsets.UTF_8)
would convert it to String.
However, I get �؉���Q�t, and doesn't seem to be converted in right way.
Why is it?
I want it to be String in Alphabet characters and numbers
Firstly, you are specifying an array of signed bytes (indicated by negative numbers):
51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119
Let's take a look at what this would hypothetically look like if it were unsigned (I used this tool for the conversion):
51, 214, 119, 171, 192, 126, 22, 127, 184, 72, 48, 190, 238, 45, 99, 137
Assuming by "Alphabet characters and numbers", you mean the English alphabet, then asciitable will help you identify each character's decimal value, but as a rough guide:
"0"-"9" = 48-57
"A"-"Z" = 65-90
"a"-"z" = 97-122
Consider the following code sample:
/**
* You can edit, run, and share this code.
* play.kotlinlang.org
*/
fun main() {
val bytes = byteArrayOf(51, -42, 119, -85, -64, 126, 22, 127, -72, 72, 48, -66, -18, 45, 99, -119)
val string = bytes.toString(Charsets.US_ASCII)
println(string)
}
As you can see, some of the values in the unsigned array fall outside of the range for English alphabetic characters and numbers, which is why you end up with a string, something like this "3�w��~�H0��-c�" depending on the charset you choose.
For reference:
Charset
Result
Charsets.US_ASCII
3�w��~�H0��-c�
Charsets.UTF_8
3�w��~�H0��-c�
Charsets.UTF_16
㏖瞫쁾ᙿ롈ゾ掉
Charsets.UTF_32
����
Charsets.ISO_8859_1
3Öw«À~¸H0¾î-c
So, it really depends on exactly which encoding the array is using, and exactly what it is you're expecting the resulting string to be.
You can play with the code above, here.

iTextSharp font widths definition not correctly loaded

I have peculiar issue with a PDF i got from a customer who used Ghostscript 9.19 to create a PDF/A compatible PDF (1.4). I want to extract text from it, using the LocationTextExtractionStrategy but I get most of the text in reversed order and with additional spaces:
expecting: abc
getting: c b a
in the content stream this might be [a,1,b,1,c] TJ
This issue has been posted to Stackoverflow before, however I cracked down the issue further than hacking my own extraction strategy. I realized that the font widths for the font used, is all zeroes and neither the metrics nor hMetrics maps are filled. I was using iTextSharp 5.5.4, but 5.5.9 still has the same issue.
This is the font:
/Subtype /Type0
/BaseFont /VGOQEA+SegoeUI
/Type /Font
/Encoding 33 0 R
/ToUnicode 48 0 R
/DescendantFonts [35 0 R]
object 33 is a CMap:
/CIDSystemInfo 32 0 R
/Filter /FlateDecode
/Length 266
/CMapName /OneByteIdentityH
/Type /CMap
object 48 is a Stream and incidentally also a CMap
object 35 finally has some width definitions
/DW 539
/CIDSystemInfo 32 0 R
/Subtype /CIDFontType2
/BaseFont /VGOQEA+SegoeUI
/FontDescriptor 26 0 R
/Type /Font
/W [0, [646], 32, [274], 40, [302, 302], 44, [217, 400, 217], 48, [539, 539, 539, 539], 53, [539, 539, 539, 539], 58, [217], 64, [955, 645, 573], 68, [701, 506], 72, [710, 266], 75, [580, 471, 898], 80, [560], 82, [598, 531], 85, [687], 87, [934], 90, [570], 97, [509, 588, 462, 589, 523, 313, 589, 566, 242], 107, [497, 242, 861, 566, 586, 588], 114, [348, 424, 339, 566], 119, [723], 122, [452], 220, [687], 228, [509], 246, [586], 252, [566]]
/CIDToGIDMap 47 0 R
In the order that iTextSharp initializes the CMapAwareDocumentFont, first the base DocumentFont gets initialized. The constructor then checks:
if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType))
it's neither.
else if (PdfName.TYPE3.Equals(subType))
it's not. Then the next else branch is entered:
PdfName encodingName = font.GetAsName(PdfName.ENCODING);
if (encodingName == null)
but since encoding is given as an indirect reference, encodingName is null. Thusly the handling of this Type0 font is never handled.
I changed this bit in the library code, but even if the method ProcessType0(font) is called, the widths values never made it to the font definition - i.e. all remained zero. This is probably to be expected. Finally I got the metrics hash map filled, but i didn't cover all the used characters. I.e. the situation got a bit better, but not all good:
instead of: abc -> c b a
I now got: abc -> acb
My only working but hacky solution to the current issue was to hack processor.DisplayPdfString((PdfString)entryObj) to adjust the textMatrix by a fixed amount. However this is no general solution and I would rather that the font would work correctly. Any other suggestions what I should try?
EDIT:
I revisited my issue using iText 7 .Net and now I get a NullReferenceException when trying to read text from my test file.
var reader = new iText.Kernel.Pdf.PdfReader(#"itextsharp_sample_locationtext_extraction_reversing_characters(1).pdf");
var extractionStrategy = new LocationTextExtractionStrategy();
var doc = new PdfDocument(reader);
var page = doc.GetFirstPage();
var test = PdfTextExtractor.GetTextFromPage(doc.GetFirstPage());
Console.WriteLine(test);
This is the file I used: https://drive.google.com/file/d/0B1RdIg0_Pbd_aTlOT2VmbnFlaTQ/view?usp=sharing
The code works for other PDF files but not for this one.
UPDATE
Thanks to mkl I know now for a while that the underlying issue is font encoding streams. Sadly I just got a message via the iText sales team that this is not on the roadmap. They claim this is issue is a weird outlier, most anybody else does not need the support for font encoding streams. So if any of you reading this does have an issue with missing support, kindly let them know by email.

How to set auto hight of page for POS software by MPDF in Yii

I am facing a problem when printing pos invoice by MPDF. I don't want to set a fixed height of pdf page. Page height will be adjusted by its content. Here the line of my controller's function from where I am calling MPDF.
$mPDF1 = Yii::app()->ePdf->mpdf('',array('80','130'), 8, '', 5, 5, 5, 5, 0, 0, 'P');
Please give me some idea how to get expected page size.
pls try this
$mpdf=new mPDF('c', 'A4', 0, 'Arial', 10, 10, 10, 10, 10, 10);
OR
$mPDF1 = Yii::app()->ePdf->mpdf('', 'A5');

Length menu being discarded due to sDom in Jquery Datatable?

I have this:
oTable = $("#bla").dataTable({
"iDisplayLength": 50,
"aLengthMenu": [[5, 25, 50, 100, 250, -1], [5, 25, 50, 100, 250, "All"]],
"sDom": "<'call-header'<'dthead'><'ttools'T><'filterinput'f>r><'dttoolbar'><'dataTables_scroll'<'dataTables_scrollBody't>><'call-footer'<'row-fluid'<'span6'i><'span6'p>>>",
.... });
If I comment out the sDom part, I get my length menu and I am able to select the number of items to show on the page. But with the SDOM variable, this just disappears.
I've tried combinations of adding:
<'dataTables_length'>
But I think I am misunderstanding how it works. Can anyone clarify how this must be done?
See the documentation for sDom - the sDom code for Length changing is l.
Here the length menu is being inserted as the very first control :
sDom: "<'call-header'<'dthead'>l<'ttools'T><'filterinput'f>r><'dttoolbar'><'dataTables_scroll'<'dataTables_scrollBody't>><'call-footer'<'row-fluid'<'span6'i><'span6'p>>>"
---^---
fiddle -> http://jsfiddle.net/eCrhb/

JavaFx 2.x : How to draw dashed or dotted lines?

I would like to dynamically change the draw of a line from solid, dotted or dashed: it seems I have to use line.setStroke, is it the correct method?
And, how to accomplish this?
Thanks
No that is not the correct method, setStroke sets the color of the stroke.
Correct method is getStrokeDashArray().add():
Line line1 = new Line(20, 40, 270, 40);
line1.getStrokeDashArray().addAll(25d, 20d, 5d, 20d);
Line line2 = new Line(20, 60, 270, 60);
line2.getStrokeDashArray().addAll(50d, 40d);
Line line3 = new Line(20, 80, 270, 80);
line3.getStrokeDashArray().addAll(25d, 10d);
Line line4 = new Line(20, 100, 270, 100);
line4.getStrokeDashArray().addAll(2d);
Line line5 = new Line(20, 120, 270, 120);
line5.getStrokeDashArray().addAll(2d, 21d);
pane.getChildren().addAll(line1, line2, line3, line4, line5);
StrokeDashArray defines the pattern of line and gap sequences. See the following different patterns as output of aboves:
Of course by manipulating the StrokeDashArray array elements you can change the pattern dynamically.