UIscrollview not scrolling swift - ios

I have the following problem, I have created view1 above view2
Then added scrollview to view1 , the scrollview contains some ui elements added by code
The problem that my scrollview is not scrolling, and the content of it appear above view 2 while I need it to be behind it and to be able to scroll it
screenshot is following
my code of adding UI elements is following
mainScrollView = UIScrollView(frame: CGRectMake(0, 0, self.view.frame.size.width, 1000))
let awesomeView2: UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.size.width, 180))
awesomeView2.load(selectedItem.listingImage);
mainScrollView.addSubview(awesomeView2);
let title: UILabel = UILabel(frame: CGRectMake(0, 180, self.view.frame.size.width, 44));
title.text = selectedItem.listingTitle;
title.textAlignment = .Right;
mainScrollView.addSubview(title);
let catName: UILabel = UILabel(frame: CGRectMake(200, 224, 120, 21));
catName.text = selectedItem.catName
catName.textAlignment = .Right;
mainScrollView.addSubview(catName);
let datePublished: UILabel = UILabel(frame: CGRectMake(0, 224, 200, 21));
datePublished.text = selectedItem.dateCreated
datePublished.textAlignment = .Left
mainScrollView.addSubview(datePublished);
let grayColor = UIColor(red: 1, green: 165/255, blue: 0, alpha: 1)
let iconsView: UIView = UIView(frame: CGRectMake(0, 250, self.view.frame.size.width, 32));
iconsView.backgroundColor = grayColor
mainScrollView.addSubview(iconsView);
if (KhawaterDataManager.instance.banners.itemBanners.count > 0) {
let awesomeView3: UIImageView = UIImageView(frame: CGRectMake(0, 282, self.view.frame.size.width, 50))
awesomeView3.load(KhawaterDataManager.instance.banners.itemBanners[0].image);
mainScrollView.addSubview(awesomeView3);
}
// test
let catName1: UILabel = UILabel(frame: CGRectMake(0, 335, self.view.frame.size.width, 50));
catName1.text = selectedItem.catName
mainScrollView.addSubview(catName1);
let catName2: UILabel = UILabel(frame: CGRectMake(0, 385, self.view.frame.size.width, 50));
catName2.text = selectedItem.catName
mainScrollView.addSubview(catName2);
let catName3: UILabel = UILabel(frame: CGRectMake(0, 435, self.view.frame.size.width, 50));
catName3.text = selectedItem.catName
mainScrollView.addSubview(catName3);
mainScrollView.contentSize = CGSizeMake(self.view.frame.size.width, 1000)
mainScrollView.scrollEnabled = true;
mainView.addSubview(mainScrollView);
please anyone tell me what is the problem here ?

Please check this line
mainScrollView.contentSize = CGSizeMake(self.view.frame.size.width, 1000)
Why content height 1000. This is too much. This should be
mainScrollView.contentSize = CGSizeMake(self.view.frame.size.width, 435+50)
And another issue is that why set your scollView as sub view of mainView rather than self.view.

Also you might want to add all subviews (awesomeView2, title, catName, etc)
to container view, and then add container view to scroll view.
something like:
let containerView: UIView = {
let view = UIView()
view.addSubview(self.awesomeView2)
view.addSubview(self.title)
view.addSubview(self.catName)
view.addSubview(self.datePublished)
return view
}()
mainScrollView.addSubview(containerView)

Related

titleView in NavigationItem doesn't consider frame height in iOS 11

I've updated to Xcode 9, and I have a titleView in my NavigationItem created in this way:
let logo = UIImageView(frame: CGRect(x: 0, y: 0, width: 70, height: 25))
logo.image = UIImage.logo
logo.contentMode = .scaleAspectFit
self.navigationItem.titleView = logo
The result is that it doesn't consider anymore the frame height.
we can control the size and position of UINavigationbar titleview. Don't use to set the imageview as titleview directly. in here create a custom UIView and then set the frame as what you need requirement and add the logo as its subview
do like
let supportVie = UIView(frame: CGRect(x: 0, y: 0, width: 70, height: 25))
// Here you can set View width and height as per your requirement for displaying supportVie position in navigationbar
//supportVie.backgroundColor = UIColor.red
let logo = UIImageView(image: UIImage.logo ) //UIImage(named: "SelectAnAlbumTitleLettering")
logo.frame = CGRect(x: 45, y: 5, width: supportVie.frame.size.width, height: supportVie.frame.size.height)
// customize the origin as (45,5) but can pass them as your requirement.
supportVie.addSubview(logo)
//supportVie.contentMode = .center;
navigationItem.titleView = supportVie

make everything clear except the fake border in swift

I'm implementing a "fake" border using a view with a background color so that the border doesn't cover another view. (as per this answer and the following code)
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
backgroundView.backgroundColor = [UIColor blackColor]; /* I want this to be clear except for the part outside bView */
backgroundView.clipsToBounds = NO;
UIView *bView = [[UIView alloc] initWithFrame:CGRectInset(backgroundView.bounds, 3, 3)];
bView.backgroundColor = [UIColor redColor]; /* I want this to be clear */
UIView *cView = [[UIView alloc] initWithFrame:CGRectMake(-50, -50, 100, 100)];
cView.backgroundColor = [UIColor yellowColor];
[bView addSubview:cView];
[backgroundView addSubview:bView];
[self.window addSubview:backgroundView];
How can I have backgroundView be clear(transparent) except for the border and bview be completely transparent? If I set both color to clear, I will lose my border. I am using swift unlike the code example.
Thanks
This is what I actually want. The big box needs to be transparent except for the fake black border around it so that the text (and everything behind it) can show up.
You say you want this:
So now I will easily construct it, but I will make the third view white so we can see it (with an annotation that it should be clear):
self.view.backgroundColor = .gray
let borderView = UIView(frame:CGRect(x: 150, y: 150, width: 200, height: 200))
borderView.backgroundColor = .clear
borderView.layer.borderWidth = 3
self.view.addSubview(borderView)
let yellowView = UIView(frame:CGRect(x: 100, y: 100, width: 100, height: 100))
yellowView.backgroundColor = .yellow
self.view.addSubview(yellowView)
let clearView = UIView(frame:borderView.frame.insetBy(dx: 3, dy: 3))
clearView.backgroundColor = .white // should be .clear
self.view.addSubview(clearView)
Result:
Substitute .clear for .white to get the desired outcome.
Well, I can't give you definitive performance data, but I would expect this to give you better performance than multiple views to create a "fake" border...
class myView: UIView {
override func draw(_ rect: CGRect) {
UIColor.black.set()
let context = UIGraphicsGetCurrentContext()
context?.stroke(rect.insetBy(dx: 1.5, dy: 1.5), width: 3.0)
}
}
let backgroundView = myView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
backgroundView.backgroundColor = UIColor.clear
let cView = UIView(frame: CGRect(x: -50, y: -50, width: 100, height: 100))
cView.backgroundColor = UIColor.yellow
backgroundView.addSubview(cView)
self.view.addSubview(backgroundView)
Of course, if you really want to do this with subviews to create the frame, this will also do the job. It adds 4 subviews to the background view, one for each side of the rectangle:
let backgroundView = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
backgroundView.backgroundColor = UIColor.clear
backgroundView.clipsToBounds = false
let bgvFrame = backgroundView.bounds
let leftEdge = UIView(frame: CGRect(x: 0, y: 0, width: 3, height: bgvFrame.size.height))
leftEdge.backgroundColor = UIColor.black
let topEdge = UIView(frame: CGRect(x: 0, y: 0, width: bgvFrame.size.width, height: 3))
topEdge.backgroundColor = UIColor.black
let rightEdge = UIView(frame: CGRect(x: bgvFrame.size.width - 3, y: 0, width: 3, height: bgvFrame.size.height))
rightEdge.backgroundColor = UIColor.black
let bottomEdge = UIView(frame: CGRect(x: 0, y: bgvFrame.size.height - 3, width: bgvFrame.size.width, height: 3))
bottomEdge.backgroundColor = UIColor.black
backgroundView.addSubview(leftEdge)
backgroundView.addSubview(topEdge)
backgroundView.addSubview(rightEdge)
backgroundView.addSubview(bottomEdge)
let cView = UIView(frame: CGRect(x: -50, y: -50, width: 100, height: 100))
cView.backgroundColor = UIColor.yellow
backgroundView.addSubview(cView)
self.view.addSubview(backgroundView)

Add text and image to UITextField right side

How do I add Text and Image on right of the UITextField.
I have a UITextField which will initially have a text/label at right of it and when user click on the button the same textField will now have text + image to the right of UITextField
Image can be added like this but what about the text/label and both ?
txtField.rightViewMode = .always
txtField.rightView = UIImageView(image: UIImage(named: "selectdrop"))
For that you can create on UIView instance and add the UILabel and UIImageView inside it then finally set that view as rightView of textField. Some thing like below.
let rightView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 60, height: 40))
label.text = "Text"
label.textColor = UIColor.red
label.textAlignment = .center
let imageView = UIImageView(frame: CGRect(x: 40, y: 0, width: 40, height: 40))
imageView.image = UIImage(named: "selectdrop")
rightView.addSubview(label)
rightView.addSubview(imageView)
txtField.rightView = rightView
txtField.rightViewMode = .always

UITableViewCell fill color with animation

Starting from the right end, I have to fill the color in UITableViewCell (or to say it better, change the background of UITableViewCell starting from right to left in a small duration). How may I achieve this ?
It's quite easy.
Just put a view in the background, starting with a 0 width and on the right of the tableview/tableview cell, then animate it to the full width of the superview.
Code snippet (in form of a Swift playground)
import UIKit
import XCPlayground
let tableView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
tableView.backgroundColor = UIColor.whiteColor()
var animatedBackroundColorView = UIView(frame: CGRect(x: tableView.frame.width, y: tableView.frame.origin.y, width: tableView.frame.width, height: tableView.frame.height))
animatedBackroundColorView.backgroundColor = UIColor.orangeColor()
tableView.addSubview(animatedBackroundColorView)
UIView.animateWithDuration(1) { () -> Void in
animatedBackroundColorView.frame = tableView.frame
}
XCPShowView("identifier", view: tableView)
Rending:
try this
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.size.width + 1,0,cell.frame.size.width,cell.frame.size.height)];
[backgroundView setBackgroundColor:yourColor];
[cell addSubview:backgroundView];
[UIView animateWithDuration:2.0 animations:^{
CGRect rect = backgroundView.frame;
rect.origin.x = 0;
[backgroundView setFrame:rect];
} completion:NULL];

How to get left padding on UITextField leftView image?

I am setting up a UIImageView as a leftView on a UITextField like so:
UIImageView *envelopeView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.height*.1, self.height*.1)];
envelopeView.image = [UIImage imageNamed:#"envelope.png"];
envelopeView.contentMode = UIViewContentModeScaleAspectFit;
envelopeView.bounds = CGRectInset(envelopeView.frame, 15, 10);
self.emailAddress.leftView = envelopeView;
self.emailAddress.leftViewMode = UITextFieldViewModeAlways;
which gets me the following:
As you can see the left size of the image goes right up to the left edge of the button even though I tried to set an inset. How can I move this envelope in so that it's got padding on all sides?
Update: I tried the proposed answer of changing the UIImageView frame like so, but the envelope is still lined up on the left side at the border of the UITextField:
CGFloat padding = 20;
UIImageView *envelopeView = [[UIImageView alloc] initWithFrame:CGRectMake(3*padding, padding, self.height*.1-padding, self.height*.1-padding)];
For Swift 3 Users
Here is what worked for me:
extension UITextField {
/// set icon of 20x20 with left padding of 8px
func setLeftIcon(_ icon: UIImage) {
let padding = 8
let size = 20
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding, height: size) )
let iconView = UIImageView(frame: CGRect(x: padding, y: 0, width: size, height: size))
iconView.image = icon
outerView.addSubview(iconView)
leftView = outerView
leftViewMode = .always
}
}
test:
txOrigin.setLeftIcon(icon_location)
result:
For Swift 4.2 +
You can use this extension:
extension UITextField {
func leftImage(_ image: UIImage?, imageWidth: CGFloat, padding: CGFloat) {
let imageView = UIImageView(image: image)
imageView.frame = CGRect(x: padding, y: 0, width: imageWidth, height: frame.height)
imageView.contentMode = .center
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: imageWidth + 2 * padding, height: frame.height))
containerView.addSubview(imageView)
leftView = containerView
leftViewMode = .always
}
}
you can simply try this:
UIImageView *envelopeView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 0, 30, 30)];
envelopeView.image = [UIImage imageNamed:#"comment-128.png"];
envelopeView.contentMode = UIViewContentModeScaleAspectFit;
UIView *test= [[UIView alloc]initWithFrame:CGRectMake(20, 0, 30, 30)];
[test addSubview:envelopeView];
[self.textField.leftView setFrame:envelopeView.frame];
self.textField.leftView =test;
self.textField.leftViewMode = UITextFieldViewModeAlways;
You can use this. Change your frame according to your need.
NSTextAttachment* placeholderImageTextAttachment = [[NSTextAttachment alloc] init];
placeholderImageTextAttachment.image = [UIImage imageNamed:#"Search"];
placeholderImageTextAttachment.bounds = CGRectMake(0, -2, 16, 16);
NSMutableAttributedString* placeholderImageString = [[NSAttributedString attributedStringWithAttachment:placeholderImageTextAttachment] mutableCopy];
NSMutableAttributedString* placeholderString = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(#" Search", nil)];
[placeholderImageString appendAttributedString:placeholderString];
_txtFieldSearch.attributedPlaceholder = placeholderImageString;
_txtFieldSearch.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

Resources