Adding UIScrollView to table cell seems to affect table scroll performance - ios

I'm not sure this was poor implementation or a poor decision to start with, but I'm attempting to add a horizontal UIScrollView inside of each cell within my UITableView. I add it is as a subview to the cell's contentView, then call cell.clipsToBounds = true (FYI, I'm using RubyMotion). When I tap a button on the cell, I use beginUpdates/endUpdates to trigger heightForRowAtIndexPath to expand the cell's height and show the "hidden" scrollview.
Anyway, since doing that my table's scroll is a bit sluggish. I've added my code below and am wondering if my implementation can be improved to fix that scroll performance. Any help/insight is helpful (though if possible I'd like to try and keep the scroll views).
my_array = [
["Hi", "there", "one"],
["Hi", "there", "two"],
["Hi", "there", "three"],
["Hi", "there", "four"],
]
scroll_frame = CGRectMake(
0, rowHeight - 1, hidden_width, 51
)
hidden_scroll = UIScrollView.alloc.initWithFrame(scroll_frame)
hidden_scroll.alwaysBounceHorizontal = true
hidden_scroll.bounces = true
hidden_scroll.contentSize = CGSizeMake(hidden_width * my_array.size, scroll_frame.size.height)
hidden_scroll.delegate = parent
hidden_scroll.clipsToBounds = true
hidden_scroll.pagingEnabled = true
hidden_scroll.showsHorizontalScrollIndicator = false
hidden_scroll.layer.borderWidth = 1
hidden_scroll.layer.borderColor = UIColor.colorWithRed(200.0/255, green:200.0/255, blue:200.0/255, alpha: 1).CGColor
hidden_scroll.backgroundColor = UIColor.colorWithRed(248.0/255, green:248.0/255, blue:248.0/255, alpha: 1)
hidden_scroll.scrollEnabled = false
my_array.each_with_index do |data, index|
hidden_view = UIView.alloc.initWithFrame(CGRectMake(
(parent.view.frame.size.width * index), 0, parent.view.frame.size.width, 50
)
)
label_frame = CGRectMake(
40, 5, (parent.view.frame.size.width - 40 - 7) * 2/3, 40
)
label = UILabel.alloc.initWithFrame(label_frame)
label.font = UIFont.boldSystemFontOfSize(11)
label.backgroundColor = UIColor.clearColor
label.text = data[0]
label.numberOfLines = 0
label.lineBreakMode = UILineBreakModeWordWrap
label_size = data[0].sizeWithFont(label.font)
label.sizeToFit
new_frame = label.frame
new_frame.origin.y = (50 - label.frame.size.height) / 2
new_frame.size.height = label.frame.size.height
label.frame = new_frame
button = UIButton.buttonWithType(UIButtonTypeCustom)
button.backgroundColor = UIColor.orangeColor
button.font = UIFont.systemFontOfSize(11)
button.setTitle(data[3].upcase, forState:UIControlStateNormal)
button.setTitleColor(UIColor.whiteColor, forState:UIControlStateNormal)
button.layer.cornerRadius = 2.0
button.instance_variable_set(:#data, data)
button_size = data[3].upcase.sizeWithFont(button.font)
button.frame = [
[label.frame.origin.x + label_frame.size.width + 5, (50 - label_size.height) / 2 - 3],
[80, button_size.height + 6]
]
button.addTarget(parent, action:"add_user_goal:", forControlEvents:UIControlEventTouchUpInside)
hidden_view.addSubview(label)
hidden_view.addSubview(button)
hidden_scroll.insertSubview(hidden_view, belowSubview: cell.contentView)
end

Since the UIScrollView isn't in view anyway, try creating the UIScrollView only when the user taps the cell to view it. Before then, there's just an empty area of the cell.
For cleaner code, I'd also recommend subclassing UIScrollView and doing your customization in a custom initializer.
class CellScrollView < UIScrollView
def initWithCustom(args={})
self.initWithFrame(args[:frame])
# ... all your customizations. Use the args hash to pass in any other data you need.
self
end
end

Related

Vertical UIStackView alignment

I have a vertical UIStackview with 3 controls in it.
I want all the controls to be centered, and the first two to expand the whole width available. The third one should take 80% of the available width and be centered as well.
Here is the result I got so far:
As you can see the third control is left aligned.
Here is the code I have for all of this:
var container = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Vertical,
Distribution = UIStackViewDistribution.EqualCentering,
Alignment = UIStackViewAlignment.Fill,
Spacing = 10f
};
// Create the Title
UILabel title = new UILabel
{
TranslatesAutoresizingMaskIntoConstraints = false,
Text = item.name,
TextAlignment = UITextAlignment.Center,
Lines = 2,
};
container.AddArrangedSubview(title);
// Create the gauge
SFCircularGauge circularGauge = new SFCircularGauge { TranslatesAutoresizingMaskIntoConstraints = false };
circularGauge.Tag = circularGauge.GenerateViewTag();
circularGauge.HeightAnchor.ConstraintEqualTo(100f).Active = true;
#if DEBUG
circularGauge.BackgroundColor = UIColor.Cyan;
#endif
container.AddArrangedSubview(circularGauge);
// Add the evaluate button
var evaluate = UIButton.FromType(UIButtonType.RoundedRect);
evaluate.TranslatesAutoresizingMaskIntoConstraints = false;
evaluate.SetTitle(Utilities.GetLocalizedString("qol_rate_button_text"), UIControlState.Normal);
evaluate.SetTitleColor(UIColor.White, UIControlState.Normal);
evaluate.BackgroundColor = new UIColor(red: 1.00f, green: 0.37f, blue: 0.00f, alpha: 1.0f); // Optimistic Orange
evaluate.Layer.CornerRadius = 5f;
evaluate.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
evaluate.ContentEdgeInsets = new UIEdgeInsets(top: 0, left: 10f, bottom: 0, right: 10f);
evaluate.UserInteractionEnabled = true;
evaluate.TouchUpInside -= Evaluate_TouchUpInside;
evaluate.TouchUpInside += Evaluate_TouchUpInside;
evaluate.Tag = evaluate.GenerateViewTag();
viewIdsAutoEvalsIds.Add((int)evaluate.Tag, item.id);
container.AddArrangedSubview(evaluate);
evaluate.WidthAnchor.ConstraintEqualTo(container.WidthAnchor, 0.8f).Active = true;
evaluate.CenterXAnchor.ConstraintEqualTo(container.CenterXAnchor).Active = true;
I can't figure out where is my problem. In the UIStackView configuration? Somewhere else?
Thanks in advance.
The property Alignment is to sets the alignment of the non-axial subviews . In your case , you need to set it as
UIStackViewAlignment.Center
instead of
UIStackViewAlignment.Fill
This might be a bug of the control. We'll see.
In the meantime, thanks again to the Reveal Tool, the gauge has no width defined.
I solved the problem by setting the width constraint explicitly:
// Fix the width to be 100% of the container
circularGauge.WidthAnchor.ConstraintEqualTo(container.WidthAnchor).Active = true;

Wrapping text on TitleLabel and DetailLabel - Material Card

I am using CosmicMind - Material Framework to create a Card. titleLabel and DetailLabel do not wrap to a new line.
My question is: What do I need to do to accomplish such task and is it supposed to be automatically adjusted by the framework?
This is what I have so far:
let card = Card()
var heartIcon = IconButton()
heartIcon = IconButton(image: Icon.favoriteBorder, tintColor: Color.red.base)
//Title Bar
let toolbar = Toolbar(rightViews: [heartIcon])
toolbar.title = cardData.cardTitleText
toolbar.titleLabel.textAlignment = .left
toolbar.titleLabel.numberOfLines = 0
toolbar.detail = "Company: " + cardData.cardTitleSubtitle
toolbar.detailLabel.font = RobotoFont.regular(with: 14)
toolbar.detailLabel.textColor = Color.grey.base
toolbar.detailLabel.textAlignment = .left
toolbar.detailLabel.numberOfLines = 0
And this is my output:
Update:
I managed to achieve what I wanted by increasing the size of the toolbar frame.
toolbar.frame = CGRect(x:0,y:0,width: view.frame.width,height: 100)
My goal was to at least show 2 lines of text.
Thanks!
I have no experience with the CosmicMind framework but usually, the label.numberOfLines property defines the maximum number of lines that the label text can have. You can set it to 2 instead of 0 and it should wrap.

scrollView doesn't adjust horizontally

Basically, I need a scrollView which is shrinked horizontally. Now, when I insert a bunch of text in it, it doesn't adjust it, text just goes over the edge of the scrollView, like this: http://prntscr.com/ai0100
This is my scrollView code:
local scrollView = widget.newScrollView
{
hideBackground = false,
hideScrollBar = true,
left = 64,
top = 0,
width = contW - 128,
height = contH,
topPadding = 256,
bottomPadding = 20,
horizontalScrollDisabled = true,
verticalScrollDisabled = false,
}
I insert a bunch of text later, and screenshot above is the result. How can I fix this?
Read this: https://docs.coronalabs.com/api/library/display/newText.html
In order to wrap a text you have to set the display.newText() width parameter accordingly.
So something like
scrollView.newText
{
text = "I am a super text"
width = 123 -- replace with your desired width
}
This is another way:
local lotsOfTextObject = display.newText( lotsOfText, display.contentCenterX-40, 0, samewidthasscrollview, 0, native.systemFont, 30)
scrollView:insert( lotsOfTextObject )

paged scrollView with labels

I'm trying to create a scrollView where u scroll between different labels. As an illustration i have this image:
I want to make the bottom scrollView i've tried creating a replicate, but in my case it is only adding "Book" to the scrollView and how can i make a smaller spacing between the labels. because in my code there are one label per self.view.frame.width
categoryArray = NSArray(objects: "Book", "Elektronik")
var textWidth = 0
for val in categoryArray!
{
var textLabel: UILabel = UILabel(frame: CGRectMake(0, CGFloat(textWidth), categoryScrollView!.frame.width, categoryScrollView!.frame.height))
textLabel.textAlignment = NSTextAlignment.Center
textLabel.text = val as NSString
categoryScrollView?.addSubview(textLabel)
textWidth = textWidth + Int(textLabel.frame.size.width)
if textWidth > Int(self.view.frame.width) {
categoryScrollView?.contentSize = CGSizeMake(CGFloat(textWidth), categoryScrollView!.frame.height);
}
}
I don't read swift very well, but it looks to me like the code is advancing the y position of the label frame on each iteration, rather than the x. In other words, change:
CGRectMake(0, CGFloat(textWidth), categoryScrollView!.frame.width, categoryScrollView!.frame.height)
to:
CGRectMake(CGFloat(textWidth), 0, categoryScrollView!.frame.width, categoryScrollView!.frame.height))

How do I remove all subviews in Rubymotion?

Basically, I have a quiz app where I add have questions, then switch to a different screen to show an expanded version of the correct answer after it is chosen. I've tried adding button and labels, but when I do this, I eventually end up with buttons and labels 'ghosting' on the screen, after I went them gone. How can I remove all subviews, so that each button and label I add from within a method appears on a fresh screen?
class MyApplicationController < UIViewController
def loadView
self.view = UIImageView.alloc.init
end
def viewDidLoad
super
view.userInteractionEnabled=true
#question_index=0
#answerChoices = []
#questionChoices=["What is best in life?",...]
makeQuestion
end
def makeQuestion
left =20
top=100
label = UILabel.new
label.text =#questionChoices[#question_index]
label.textAlignment = UITextAlignmentCenter
label.textColor = UIColor.redColor
label.frame = [[20,20], [view.frame.size.width-40, 40]]
label.lineBreakMode = UILineBreakModeWordWrap
label.numberOfLines = 0
label.sizeToFit
view.image = UIImage.imageNamed('background.jpg')
view.addSubview(label)
4.times do |i|
#button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#button.setTitle(#answerChoices[i][#question_index], forState:UIControlStateNormal)
#button.frame = [[left, top], [view.frame.size.width - left * 2, 40]]
#button.addTarget(self, action:'actionTapped:', forControlEvents:UIControlEventTouchUpInside)
#button.tag=i
top+=45
view.addSubview(#button)
end
end
def makeAnswer
#button.removeFromSuperview
#button.removeFromSuperview
#button.removeFromSuperview
#button.removeFromSuperview
view.image = UIImage.imageNamed('back.jpg')
label = UILabel.new
label.text =#rightArray[#question_index]
label.textAlignment = UITextAlignmentCenter
label.textColor = UIColor.blackColor
label.frame = [[20,20], [view.frame.size.width-40, 40]]
label.lineBreakMode = UILineBreakModeWordWrap
label.numberOfLines = 0
label.sizeToFit
view.addSubview(label)
#button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#button.setTitle("More questions", forState:UIControlStateNormal)
#button.tag=1
#button.addTarget(self, action:'makeQuestion', forControlEvents:UIControlEventTouchUpInside)
#button.frame = [[20, 100], [view.frame.size.width - 20 * 2, 40]]
view.addSubview(#button)
end
end
You need an array of buttons. In your 4.times loop, you are overwriting the instance variable #button four times. Instead, make #button an array of buttons, and assign a different button to each index.
If you have a variable myView and want to remove all of its subviews, I believe this will work:
myView.subviews.each {|sv| sv.removeFromSuperview}

Resources