how to make my image behind my labels? - ios

my label and toolbar disappear from the view when i run the app hidden behind my image
this is my viewdidload code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var tiger1 = Tigers()
tiger1.name = "BengalTiger"
tiger1.age = 1
tiger1.breed = "Bengal"
tiger1.fact = "live in the bengal area"
tiger1.image = UIImage(named: "BengalTiger.jpg")!
self.nameLabel.text = tiger1.name
self.ageLabel.text = String(tiger1.age)
self.breedLabel.text = tiger1.breed
self.factLabel.text = tiger1.fact
self.imageView.image = tiger1.image
tigersArray.append(tiger1)
}
and this is my struct:
struct Tigers {
var image = UIImage(named: "")
var name = ""
var age = 0
var breed = ""
var fact = ""
}

Natives metods
insertSubview:(UIView *) aboveSubview:(UIView *)
or
insertSubview:(UIView *) belowSubview:(UIView *)

You can use:
self.view.sendSubviewToBack(imageView)
and that will put it behind your other views
Here you see the imageView in the back of the other view elements, so the button and label will be shown on top of the image view:
Below you see the elements are behind the image view so they will be covered up by the image.
You can arrange elements in the document outline by dragging them up and down.

Related

How to wrap ViewController content inside MDCTabBarView container?

I'm trying to implement a MDCBottomNavigationBar which contains a MDCTabBarView, which in turn contains 2 other views (shown as tabbed).
In my main controller I create the 4 controllers for the menu items at the bottom and implement MDCTabBarViewDelegate. When the user taps on a bottom menu item, they are presented with the corresponding controller. Now I want one of the controllers to contain a tab bar at the top, as shown in the demo image below. I have created the same MDCTabBarViewDelegate with 2 controllers and added them to the view. They are shown and they are switching whenever I change the tabs, but there are issues with how it looks. So, Tab 2 should contain the tab bar with App and All, and underneath the tab bar, the content of each tab should be shown.
Please check this image:
Simulator Demo Image
The Green area should actually be the content of Tab 2 -> App. The problem is the Green area is displayed on the entire screen, instead of being displayed under the tab bar. The second problem is that my view controllers are showing a faded bar above the bottom menu. I tried to hide that bar with navigationController?.navigationBar.isHidden = true but nothing seems to work.
Can someone help me with the 2 issues above? I can't find a single resource / documentation about how to use this component on iOS. It would be great if you could even share some docs that I can read by myself, if not the answer.
Parent view controller:
class HomeController: UITabBarController {
let firstC = FirstController()
let secondC = SecondController()
let thirdC = ThirdControllerController()
let fourthC = FourthController()
let bottomNavBar: MDCBottomNavigationBar = {
let bottomNavBar = MDCBottomNavigationBar()
bottomNavBar.titleVisibility = .always
bottomNavBar.alignment = .justifiedAdjacentTitles
return bottomNavBar
}()
let firstItem: MDCTabBarItem = {
let firstItem = MDCTabBarItem()
firstItem.title = "Tab 1"
firstItem.image = UIImage(systemName: "house.fill")
firstItem.tag = 0
return firstItem
}()
let secondItem: MDCTabBarItem = {
let secondItem = MDCTabBarItem()
secondItem.title = "Tab 2"
secondItem.image = UIImage(systemName: "house.fill")
secondItem.tag = 1
return secondItem
}()
let thirdItem: MDCTabBarItem = {
let thirdItem = MDCTabBarItem()
thirdItem.title = "Tab 3"
thirdItem.image = UIImage(systemName: "house.fill")
thirdItem.tag = 2
return thirdItem
}()
let fourthItem: MDCTabBarItem = {
let fourthItem = MDCTabBarItem()
fourthItem.title = "Tab 4"
fourthItem.image = UIImage(systemName: "house.fill")
fourthItem.tag = 3
return fourthItem
}()
override func viewDidLoad() {
super.viewDidLoad()
bottomNavBar.delegate = self
bottomNavBar.items = [firstItem, secondItem, thirdItem, fourthItem]
self.viewControllers = [
firstC,
secondC,
thirdC,
fourthC
]
view.addSubview(bottomNavBar)
}
}
// SecondC - inner controller
class SecondController: UITabBarController {
let firstC = TabFirstC()
let secondC = TabSecondC()
let firstTab: MDCTabBarItem = {
let tab = MDCTabBarItem(title: "App", image: nil, tag: 0)
return tab
}()
let secondTab: MDCTabBarItem = {
let tab = MDCTabBarItem(title: "All", image: nil, tag: 1)
return tab
}()
let tabs: MDCTabBarView = {
let tabs = MDCTabBarView()
tabs.translatesAutoresizingMaskIntoConstraints = false
return tabs
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tabs)
viewControllers = [firstC, secondC]
tabs.tabBarDelegate = self
tabs.items = [firstTab, secondTab]
tabs.selectedItem = firstTab
NSLayoutConstraint.activate([
tabs.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
tabs.topAnchor.constraint(equalTo: logoImageView.safeAreaLayoutGuide.bottomAnchor, constant: 10),
tabs.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
])
}
}

UIView default properties and custom properties

I created UIView with default properties
var color = Label.Color.black { didSet{ setNeedsDisplay() }}
var count = Label.Count.one.rawValue { didSet{ setNeedsDisplay() }}
var shading = Label.Shading.empty { didSet{ setNeedsDisplay() }}
var shape = Label.Shape.triangle { didSet{ setNeedsDisplay() }}
var isSelected = false
And then I add some subviews using the same UIView in ViewController
func addCardsOnGridView() {
grid.frame = cardsView.bounds
grid.cellCount = game.cardsOnDeck.count
for cardView in cardsView.subviews{
cardView.removeFromSuperview()
}
for index in 0..<grid.cellCount {
if let cellFrame = grid[index] {
let card = game.cardsOnDeck[index]
let cardView = CardsView(frame: cellFrame.insetBy(dx: CardSize.inset, dy: CardSize.inset))
cardView.color = card.label.color
cardView.count = card.label.count.rawValue
cardView.shape = card.label.shape
cardView.shading = card.label.shading
//cardView.isSelected = card.isSelected
//print(cardsView.isSelected)
cardsView.addSubview(cardView)
} else {
print("grid[\(index)] doecnt exist")
}
}
}
and then I got this UIView with default comes as superview and subviews above superview:
How can I remove view with default UIView properties and redraw with custom properties?
I can't understand your question completely. What I understand is that you want to get specific view like triangle view.
One way to achieve this is by assigning tag to every subview like below when you are adding them in mainView
aView.tag = 6
and then when you want to get a subview, you can get using viewWithTag function like below
if let aCustomView = mainView.viewWithTag(6) as? CustomView {
aCustomView.myColor = .blue
}
An other way to get custom view is by looping thought subview and try to cast view into custom class like below
mainView.subviews.forEach({ (aView) in
if aView.tag == 6,
let customView = aView as? CustomView {
customView.myColor = .blue
}
})

How to add multiple images in single image view and to show all images for every 2 second continuously

I have one view controller and I kept one full mage view in that view controller.And i have some image name like 1.png,2.png,3.png , like 6 images.What I need is I need to show as like slide .i.e for every 2 second one image should be in image view. I have done it in Objective-C. But I am beginner in Swift, so not able to do it. How to do this?
#implementation ViewController {
UIImageView* imgView; // your UIImageView
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[self navigationController] setNavigationBarHidden:YES animated:YES];
UIImage* img1 = [UIImage imageNamed:#"11.jpg"];
UIImage* img2 = [UIImage imageNamed:#"s2.jpg"];
imgView = [[UIImageView alloc] initWithFrame:self.view.frame]; // create a UIImageView with the same size as the view.
imgView.animationImages = #[img1, img2]; // use a nice NSArray literal to pass in your images.
imgView.animationDuration = 2.0*2.0; // 2 seconds for each image (x3 images)
[self.view addSubview:imgView]; // add UIImageView to view
[imgView startAnimating]; // start animating
}
Like that in Swift I need to do :
I am having image view name as imagview.And please don't compare the Obj-C code. Because there I have added some library file for animating. Can i code to do this continuous image showing for every 2 seconds in Swift?
var imagesListArray = [UIImage]()
for imageName in 1...3
{
imagesListArray.append(UIImage(named: "\(imageName).png")!)
}
// You can also use below code to add images if not want to use loop
// imagesListArray.append(UIImage(named: "1.png")!)
// imagesListArray.append(UIImage(named: "2.png")!)
// imagesListArray.append(UIImage(named: "3.png")!)
self.imageView.animationImages = imagesListArray
self.imageView.animationDuration = 2.0
self.imageView.startAnimating()
if let urlStringArr : NSArray = tempDic["get_image"] as? NSArray
{
if urlStringArr.count != 0
{
var imagesListArray = [UIImage]()
if urlStringArr.count > 1
{
for i in 0..<urlStringArr.count
{
let url = URL(string:urlStringArr[i] as! String)
if let data = try? Data(contentsOf: url!)
{
let image: UIImage = UIImage(data: data)!
imagesListArray.append(image)
}
}
cell.imagePet.animationImages = imagesListArray
cell.imagePet.animationDuration = 5.0
cell.imagePet.startAnimating()
}
else
{
if let getUrlString : String = urlStringArr[0] as? String
{
if getUrlString != ""
{
cell.imagePet.sd_setImage(with: URL(string:getUrlString), placeholderImage:nil)
}
}
}
}
}
I am using Xcode 11.3.1 and Swift 5.2.
Say you have an image array and UIImageView as follows:
var images = [UIImage]()
#IBOutlet weak var imageView: UIImageView!
Then you can set all images to UIImageView and start animating by following code:
imageView.animationImages = images
imageView.animationDuration = 2 * images.count
imageView.startAnimating()
The animationDuration is the amount of time it takes to go through one cycle of the images.

Trigger an event (tableview reload) whenever a text is in a certain position of a textView in iOS

I just started with iOS programming and I could not find anywhere an answer about this.
I have a Textview, containing a large text divided in paragraphs.
I would like to trigger the reload of a Tableview whenever each paragraph reaches the middle of the TextView.
How could I do it?
Here is the code I wrote so far:
#IBOutlet weak var testo: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
if databaseDB.open() {
// Here I definethe string attributes
var style = NSMutableParagraphStyle()
style.lineSpacing = 15
let font = UIFont(name: "Georgia", size: 18.0) ?? UIFont.systemFontOfSize(18.0)
let textFont = [NSFontAttributeName:font, NSParagraphStyleAttributeName : style]
let fontSuper = UIFont(name: "Georgia-Italic", size: 13.0) ?? UIFont.systemFontOfSize(13.0)
let superFont = [NSFontAttributeName:fontSuper, NSBaselineOffsetAttributeName:6]
// and here the variables
let mainText = NSMutableAttributedString()
var paragraphId : String = ""
// I load the text from a table in the database
let querySQL = "SELECT id, versetext FROM table1"
let results:FMResultSet? = databaseDB.executeQuery(querySQL, withArgumentsInArray: nil)
while results!.next(){
paragraphId = results!.stringForColumn("id")
// I add some other information from another table (here goes also other code, but I have skipped it for simplicity)
let queryDescrSQL = "SELECT paragraph FROM table2 WHERE id = \(paragraphId)"
let paragraphResults:FMResultSet? = databaseDB.executeQuery(queryDescrSQL, withArgumentsInArray: nil)
if paragraphResults?.next() == true {
// here I add the attributes to the text to be shown
let numberParagraph = paragraphResults!.stringForColumn("paragraph")
let paragraphNumber = NSAttributedString(string: numberParagraph, attributes:superFont)
mainText.appendAttributedString(paragraphNumber)
let textParagraph = results!.stringForColumn("versetext")+" "
let paragraphText = NSAttributedString(string: textParagraph, attributes:textFont)
mainText.appendAttributedString(paragraphText)
}
}
databaseDB.close()
// and finally everything is loaded on the TextView
testo.attributedText = mainText
}
}
// I'm letting out the code for the TableView, as it is probably not relevant for the matter
I was thinking of adding some other attribute to paragraphNumber, something like here, but I haven't been able to find how to do it.
Thanks in advance,
Silvo
It's not clear how your paragraphs are divided up (is each in its own UITextView, or do they all form one large text view), but the basics of this are that you need to reload a table view when the scroll view reaches a certain scrolled position.
UITableView has a method reloadData, so call this when your scroll view is at the position.
Scrolling a scroll view just means you are modifying its contentOffset, and the scroll view sends its delegate a message every time the content offset changes. Make your controller the delegate of the scroll view, and implement the scrollViewDidScroll(_:) delegate method. In here, check the current content offset, and if it's at the value you're looking for, reload the table view:
class MyViewController: UIViewController, UIScrollViewDelegate {
// var scrollView = ...
// var tableView = ...
override viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// var scrollThreshold = (calculate some scroll threshold based on your paragraph text)
if scrollView.contentOffset.y > scrollThreshold {
tableView.reloadData()
}
}
}

Swift - How to animate Images?

I'm trying to animate images in particular time- duration. It is working fine in Objective C. However, it is not working for Swift, where is my mistake?
The code for Objective-C is -
-(void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *imgListArray=[NSMutableArray array];
for (int i=0; i<=11; i++)
{
NSString *strImageName=[NSString stringWithFormat:#"c%d.png", i];
NSLog(#"%#",strImageName);
UIImage *image=[UIImage imageNamed:strImageName];
[imgListArray addObject:image];
}
self.imgView.animationImages = imgListArray;
self.imgView.animationDuration =1.0f;
[self.imgView startAnimating];
// Do any additional setup after loading the view, typically from a nib
}
The Code for swift is-
override func viewDidLoad()
{
super.viewDidLoad()
var imgListArray :NSMutableArray = []
for countValue in 1...11
{
var strImageName : String = "c\(countValue).png"
var image = UIImage(named:strImageName) // suggested by Anil
imgListArray.addObject(image)
}
// Swift code HERE for Objective c
}
[UIImage imageNamed (strImageName)]
This not swift code. In swift it would be
UIImage(named:strImageName)
Modified code:
var imgListArray :NSMutableArray = []
for countValue in 1...11
{
var strImageName : String = "c\(countValue).png"
var image = UIImage(named:strImageName)
imgListArray .addObject(image)
}
self.imageView.animationImages = imgListArray;
self.imageView.animationDuration = 1.0
self.imageView.startAnimating()
for Swift 2, use [UIImage] instead.
var images: [UIImage] = []
for i in 1...2 {
images.append(UIImage(named: "c\(i)")!)
}
myImageView.animationImages = images
myImageView.animationDuration = 1.0
myImageView.startAnimating()
In swift you can go one step further and have a simple line to do this:
let loadingImages = (1...11).map { UIImage(named: "c\($0)")! }
Then you can do the rest and inject this into an imageView
self.imageView.animationImages = loadingImages
self.imageView.animationDuration = 1.0
self.imageView.startAnimating()
In swift 3 - Create Array of images and just animate that.
func animate_images()
{
let myimgArr = ["1.jpg","2.jpg","3.jpg"]
var images = [UIImage]()
for i in 0..<myimgArr.count
{
images.append(UIImage(named: myimgArr[i])!)
}
imgView_ref.animationImages = images
imgView_ref.animationDuration = 0.04
imgView_ref.animationRepeatCount = 2
imgView_ref.startAnimating()
}
And for stop animation just write
imgView_ref.stopAnimating()
Swift 3+
UIImageViews can animate images in two different ways (the other answers already cover the first way in deep):
Create an [UIImage] array with the images to animate
Set the animationImages property of the view with this array
Set the animationDuration property
Start the animation
Encapsulate the animation in an UIImage using animatedImage(with:duration:)
Set the normal image property of the view
The following code uses #imageLiterals:
let images = [img1, img2, img3] // use of #imageLiterals here
let animation = UIImage.animatedImage(with: images, duration: 1)
self.myImageView.image = animation
Pro:
If you have to change the image of an UIImageView a lot and maybe one of those images should be animated, then you don't have to start/stop the animation every time anymore neither you need to set the animatedImages property back to nil to display the image stored in the image property of the image view.
Con:
You can't start/stop the animation, if it's encapsulated in a single UIImage instead of an array.
More on #imageLiterals:
If you want to use an image literal, either type imageLiteral or just type the name of an image from your assets folder and Xcode's code completion will suggest it.
Further reading:
Another good blog post about using #imageLiterals and #colorLiterals with animations to follow.
another approach if you want to animate an array of images:
var counter = 1
var timer = NSTimer()
#IBOutlet weak var someImg: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: Selector("doSomeAnimation"), userInfo: nil, repeats: true)
}
func doSomeAnimation() {
//I have four pngs in my project, which are named frame1.png ... and so on
if counter == 4 {
counter = 1
}else {
counter++
}
someImg.image = UIImage(named: "frame\(counter).png")
}
Hope it helps!!
For anyone running multiple animations, depending on a variable, try the below.
For example, you could run an animation sending 0 or 1 (maybe based on if your app knows its daytime or nighttime):
func runAnimation (imgView: UIImageView, arrayPos: Int) {
let timingArray = [7.0,10.0] //Durations of each
let frameArray = [43,45] //Frames for each
var imgArray: Array<UIImage> = [] //Setup empty array
for i in 1 ... frameArray[arrayPos] {
//Fill empty array with images!!
let imageToAdd = UIImage(named: "animationNum_\(arrayPos)-frameNum_\(i)")
imgArray.append(imageToAdd!)
}
imgView.animationImages = imgArray
imgView.animationDuration = timingArray[arrayPos]
imgView.animationRepeatCount = 2
imgView.startAnimating()
}

Resources