質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1427閲覧

Swift BottomNavigationBar で特定のItemだけ画像で表示するやり方

ludolf

総合スコア39

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/08/11 06:56

編集2020/08/12 09:42

いつもお世話になっております。

表題の件で分からないため本件を立てております。
特定のItemだけ画像で表示しようとしていて、色々調査した結果レンダリングモードというUIImageの表示の仕方を変更すれば実現できそうだと思い、実装したのですがうまく反映されていません、、

公式サイトは以下です。
https://developer.apple.com/documentation/uikit/uiimage/renderingmode

念のため申し上げますと、bottomnavigationbarはGoogleが提供しているマテリアルデザインを採用しています。
詳細は以下です。
https://material.io/develop/ios/components/bottomnavigation

下記が実際に記述しているコードです。storyboardは何もいじっておりません。

viewController

swift

1 2import UIKit 3import MaterialComponents.MaterialBottomNavigation 4import MaterialComponents 5import IconFontStack 6 7class ViewController: UIViewController { 8 9 let bottomNavBar = MDCBottomNavigationBar() 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 15 viewDidLoadNavigation() 16 17 } 18 19 func viewDidLoadNavigation() { 20 21 let size = bottomNavBar.sizeThatFits(view.bounds.size) 22 23 let bottomNavBarFrame = CGRect(x: 0,y: view.bounds.height - size.height,width: size.width,height: size.height) 24 25 bottomNavBar.frame = bottomNavBarFrame 26 27 let homeItem = UITabBarItem( 28 title: "Home", 29 image: UIImage(icon: .googleMaterialDesign(.home), size: CGSize(width: 40, height: 40)), 30 tag: 0) 31 let messagesItem = UITabBarItem( 32 title: "問題の画像", 33 image: UIImage(named: "register_icon")?.withRenderingMode(.alwaysOriginal), 34 tag: 1) 35 messagesItem.badgeValue = "8" 36 let favoritesItem = UITabBarItem( 37 title: "Favorites", 38 image: UIImage(icon: .fontAwesome(.starO), size: CGSize(width: 40, height: 40)), 39 tag: 2) 40 favoritesItem.badgeValue = "" 41 let readerItem = UITabBarItem( 42 title: "Reader", 43 image: UIImage(icon: .fontAwesome(.signIn), size: CGSize(width:40, height: 40)), 44 tag: 3) 45 readerItem.badgeValue = "88" 46 47 let birthdayItem = UITabBarItem( 48 title: "ic_birthday", 49 image: UIImage(icon: .googleMaterialDesign(.accountCircle), size: CGSize(width:40, height: 40)), 50 tag: 4) 51 birthdayItem.badgeValue = "888+" 52 bottomNavBar.items = [homeItem, messagesItem, favoritesItem, readerItem, birthdayItem] 53 bottomNavBar.selectedItem = homeItem 54 55 view.addSubview(bottomNavBar) 56 57 } 58 59 60}

実際の画面
イメージ説明

よろしくお願いします!

追記

イメージ説明

ずっと黒・グレイでitemが表示されていたので、tintColorが悪さしてるんじゃないかと思って色々調べていたらライブラリの初期値が黒とグレイでした、、
このデフォルト値をOverrideでnilに出来ますでしょうか?
自分がやったこととしてはtintColorDidChange()を使って変更しようとしてもnilが渡せませんでした。

上記が関係しているかは、分かりませんがどんな意見でもいいのでご教授いただければと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tsuki01

2020/08/12 12:31 編集

現在の問題としては、画像設定しても全て塗りつぶされて(四角いグレー状態で)表示されるということでしょうか? また、画像はどの様なものを利用していますでしょうか? ※ファイル形式(png、jpg)、ファイルサイズ(width、height)
ludolf

2020/08/13 00:58

ご質問ありがとうございます! はいtsuki01さんが仰る通り画像そのものの色を表示しようとした際にすべて塗りつぶされてしまう現象に悩んでおります。 色んな参考サイトで画像をそのまま表示するには、レンダリングを使用して表示するのが基本らしいのでやってみたのですが、必ず塗りつぶされてしまいます、、 後日色々調べていると何も色を指定していなければtintcolorがついてしまうという記事を見つけ、nilを入れ込むことにより解決できるという記事をみたので追記した経緯になります。
guest

回答1

0

ベストアンサー

2020.8.13追記

完全な解決方法とはなりませんが、追加調査分を共有情報として追記させて頂きます。
※かなり「無理やりやってみた」感がありますので、おすすめも動作保証も出来ないですが。。

1、「MDCBottomNavigationItemView.m」クラス内にて、RenderingModeが"AlwaysTemplate"で設定されている
以下二つのメソッド内で RenderingMode が設定されているので、ViewController側で指定しても反映されていないのかもしれない(?)
なので、以下メソッド内の RenderingMode 指定部分を無理やり変更すれば問題を回避できる可能性あり。
・(void)setImage:(UIImage *)image
・(void)setSelectedImage:(UIImage *)selectedImage

2、ViewController側でのRenderingMode設定を工夫すると、以下の様にそれっぽい(画像の元の色を)表現できる
「bottomNavBar.items」変数に各Itemが入っているので、各Itemに対してRenderingModeを再指定すると以下の様に表示可能になる。(ライオンの画像を出してます)
※上:選択時、下:未選択時
選択時
未選択時


以下は実現したい内容と異なっていたため、以下回答は無視してください

~~コメントにも質問記載しましたが、以下の様なことを実現したいということでしょうか。
もし認識が違っていたらスルーしてください。
~~
TabBar


~~
もっと良い方法があるかもしれませんが、上記に関しては、処理を以下の様にしたら対応できました。
対応点としては、「画像ファイル指定箇所の修正」、「UIImageのextension追加」の2点になります。
※画像のサイズ指定部分は、参考サイト からのコピペになります。
~~

Swift

1import UIKit 2import MaterialComponents.MaterialBottomNavigation 3import MaterialComponents 4import IconFontStack 5 6class ViewController: UIViewController { 7 8 let bottomNavBar = MDCBottomNavigationBar() 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 13 viewDidLoadNavigation() 14 } 15 16 func viewDidLoadNavigation() { 17 18 let size = bottomNavBar.sizeThatFits(view.bounds.size) 19 20 let bottomNavBarFrame = CGRect(x: 0,y: view.bounds.height - size.height,width: size.width,height: size.height) 21 22 bottomNavBar.frame = bottomNavBarFrame 23 24 let homeItem = UITabBarItem( 25 title: "Home", 26 image: UIImage(icon: .googleMaterialDesign(.home), size: CGSize(width: 40, height: 40)), 27 tag: 0) 28 let messagesItem = UITabBarItem( 29 title: "問題の画像", // ↓以下行を変更 30 image: UIImage(named: "animal")?.imageResize(sizeChange: CGSize(width: 40, height: 40)), 31 tag: 1) 32 messagesItem.badgeValue = "8" 33 let favoritesItem = UITabBarItem( 34 title: "Favorites", 35 image: UIImage(icon: .fontAwesome(.starO), size: CGSize(width: 40, height: 40)), 36 tag: 2) 37 favoritesItem.badgeValue = "" 38 let readerItem = UITabBarItem( 39 title: "Reader", 40 image: UIImage(icon: .fontAwesome(.signIn), size: CGSize(width:40, height: 40)), 41 tag: 3) 42 readerItem.badgeValue = "88" 43 44 let birthdayItem = UITabBarItem( 45 title: "ic_birthday", 46 image: UIImage(icon: .googleMaterialDesign(.accountCircle), size: CGSize(width:40, height: 40)), 47 tag: 4) 48 birthdayItem.badgeValue = "888+" 49 bottomNavBar.items = [homeItem, messagesItem, favoritesItem, readerItem, birthdayItem] 50 bottomNavBar.selectedItem = homeItem 51 52 view.addSubview(bottomNavBar) 53 54 } 55} 56 57// extention追加 58// 参考URL:https://stackoverflow.com/questions/24709244/how-do-set-a-width-and-height-of-an-image-in-swift/40212757 59extension UIImage { 60 61 func imageResize (sizeChange:CGSize)-> UIImage{ 62 63 let hasAlpha = true 64 let scale: CGFloat = 0.0 // Use scale factor of main screen 65 66 UIGraphicsBeginImageContextWithOptions(sizeChange, !hasAlpha, scale) 67 self.draw(in: CGRect(origin: CGPoint.zero, size: sizeChange)) 68 69 let scaledImage = UIGraphicsGetImageFromCurrentImageContext() 70 return scaledImage! 71 } 72} 73

投稿2020/08/12 13:01

編集2020/08/13 08:10
tsuki01

総合スコア1751

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ludolf

2020/08/13 01:15

ご回答ありがとうございます! 「実際の画面」が分かりずらく申し訳ございません、、 PNG画像でシルエットのみ表示するのではなく画像をそのまま表示したいです。 materialデザインの推奨項目にフッタータブメニューはフッターの背景・itemのアクティブ時・非アクティブ時の計3色までを使用することと記述されていたので、画像をそのまま表示した際に2色以上の場合もあるので、もともと塗りつぶしモードしかできないのではないかと考えてもおります。 ライブラリで本件を解決するのは難しいでしょうか? 余談ですが、上の人に画像で表示するのは非推奨ですと伝えているのですが、どうしてもその画像を表示させて目立たせたいということで無理に画像を表示しようとさせています、、泣
tsuki01

2020/08/13 02:13

やりたいことと、余談に関して理解しました。 的外れな回答をしてしまい申し訳ありませんでした。。 普通のTabBarControllerであれば、質問者様が記載していたレンダリングモードで指定できるのかもしれませんが、こちらのライブラリに関してはパッと回答が分からない状態となります。 お役に立てず、重ねてお詫び申し上げます。 ※また追記部分のtintColorですが、以下の様な記載をすれば色の変更は出来ますが"nil"には出来なさそうでした。 let bottomNavBar = MDCBottomNavigationBar() bottomNavBar.selectedItemTintColor = UIColor.clear // nilを設定するとコンパイルエラー(ライブラリ側の処理を直接変更するしかない?)
ludolf

2020/08/13 04:37

>お役に立てず、重ねてお詫び申し上げます。 いえいえとんでもないです汗 誰も回答してくれず、寂しかったのでどんな回答でも嬉しいです! >普通のTabBarControllerであれば、質問者様が記載していたレンダリングモードで指定できるのかもしれませんが 上記ですがとても有力な情報ですありがとうございます! あるアプリで画像を表示しているアプリがあったのですが、やはりそちらでは普通のTabBarControllerを使用していましたか、 >※また追記部分のtintColorですが、以下の様な記載をすれば色の変更は出来ますが"nil"には出来なさそうでした。 そうですよね、自分もnilを入れてみたのですが、nilを入れるなと怒られました、 clearを実装すると選択された項目が何も表示しなくなりました。 やはりライブラリを直接触らないと実現出来なさそうですよね、、 原因が確信できたのでベストアンサーにしたいと思います!
tsuki01

2020/08/13 08:12 編集

完全に解決していないのに、ベストアンサーを頂いて申し訳ないくらいです。 回答に一応追記しましたが、RenderModeが反映されないのは、ライブラリ内の以下が原因かもしれませんね。何かスッキリとした解決方法が見つかりましたら、是非追記をお願いしたいです。 ・「MDCBottomNavigationItemView.m」クラス内にて、RenderingModeが"AlwaysTemplate"で設定されている。
ludolf

2020/08/13 09:22

上記見ました! >「MDCBottomNavigationItemView.m」クラス内にて、RenderingModeが"AlwaysTemplate"で設定されている。 そこでしたかー汗 tintColorを入れ込んでいるところをnilにしてみたんですが、全てUIColor.Clearになってしまいすごく悩んでいました。結局templateになって単色にしかできなかったんですね、 上記でできました、大変助かりました^^ 勝手ながらフォローしております今後ともよろしくお願いします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問